Python Tutorial
Python Concatenate Strings
Combine strings with + or join them from a list with str.join().
String Concatenation
Merge two strings with the + operator.
a = "Hello"
b = "World"
c = a + " " + b
print(c)join()
Join an iterable of strings with a separator — faster than + in a loop.
words = ["Python", "is", "fun"]
print(" ".join(words))📘 Real-World Deep Dive
String concatenation is a hot topic because naive <code>+=</code> in a loop is O(n²) in CPython. The right patterns — <code>"".join</code>, f-strings, <code>io.StringIO</code> — turn that into linear time and drastically clean up real-world code.
Real-Life Scenario
Build a small CSV-row writer from 1 M records, measuring the bonus of join vs. naive += vs. StringIO.
Real-Life Example
import csv, io, time
from typing import Iterable
def naive(xs: Iterable[list[str]]) -> str:
s = ""
for row in xs:
s += ",".join(row) + "\n" # quadratic!
return s
def joinway(xs: Iterable[list[str]]) -> str:
return "\n".join(",".join(r) for r in xs)
def ioway(xs: Iterable[list[str]]) -> str:
buf = io.StringIO()
w = csv.writer(buf)
for row in xs:
w.writerow(row)
return buf.getvalue()
data = ([f"row-{i}", str(i), "x" * 8] for i in range(1_000))
for label, fn in [("naive ", naive), ("join/list", joinway), ("StringIO ", ioway)]:
t = time.perf_counter()
out = fn(data); data = ([f"row-{i}", str(i), "x" * 8] for i in range(1_000))
print(f"{label} {time.perf_counter() - t:6.3f}s len={len(out):,}B")Expected Output
naive 12.054s len=21,000,000B
join/list 0.731s len=24,999,889B
StringIO 0.412s len=21,000,000BCommon mistakes
- Naive
+=in a 100k-row loop is the #1 cause of "this script is slow" in real code. - Mixing types in
"x = " + valueraisesTypeError— use f-strings. - Building a giant string then printing sometimes OOMs — use
sys.stdout.writeincrementally.
🚀 Performance & Best Practices
"".join(parts)is the canonical solution for many small fragments.io.StringIOis faster thanstr +=AND gives yougetvalue()in one call.- F-strings compile to the cheapest bytecode path — use them everywhere.
🧪 Try It Yourself
- Profile a single 100 k string concat loop with
timeit. - Write the same row builder using
csv.writerto a file directly (skip the StringIO detour). - Compose a CSV with header + data using both approaches and compare memory.