While I do get your point, Python likes making optimizations. They rarely, if ever, make patterns slower by choice. There's nothing in any spec that says it _has_ to be slow: that's as much as an implementation detail as "joining lists are fast".
In [18]: sys.version
Out[18]: '3.9.1 (default, Feb 3 2021, 07:38:02) \n[Clang 12.0.0 (clang-1200.0.32.29)]'
In [6]: strings = ["".join(random.choice(string.hexdigits) for _ in range(10)) for _ in range(10)]
In [9]: def one():
...: "".join(s for s in strings)
...:
In [10]: def two():
...: "".join([s for s in strings])
...:
In [11]: def three():
...: x = []
...: for s in strings:
...: x.append(s)
...: "".join(x)
...:
In [12]: def four():
...: x = ""
...: for s in strings:
...: x += s
...:
In [13]: %timeit one()
753 ns ± 9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [14]: %timeit two()
521 ns ± 5.63 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [15]: %timeit three()
696 ns ± 3.94 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [16]: %timeit four()
620 ns ± 4.82 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)