datarekha

Why are Python strings immutable, and how does string interning affect memory?

The short answer

Strings are immutable so they can be safely shared (interned), used as dict keys, and passed across threads without locks. Every operation that looks like mutation — slicing, concatenation, `.replace()` — returns a new string object. Interning means CPython may store only one copy of a string literal and reuse it, saving memory for repeated identifiers and short strings.

How to think about it

Why the design choice matters

This isn’t just trivia — immutability is what makes strings safe to use as dict keys, share between threads, and cache aggressively. If strings were mutable, changing a string after using it as a dict key would make the entry unreachable. Interning wouldn’t be safe at all.

Immutability in practice — nothing mutates in place

Every operation that looks like it changes a string actually creates a new one:

s = "hello"
s[0] = "H"       # TypeError — item assignment not supported
s2 = s.upper()   # new string object, s is unchanged
s3 = s + " world"  # another new object

The original s is never touched. This is guaranteed by the language, not just CPython.

Interning and identity

Efficient string building — avoid += in loops

Because every += allocates a new string and copies all previous characters, concatenating n strings in a loop costs O(n²) total:

# Bad — O(n²): each += copies everything
result = ""
for word in words:
    result += word + " "

# Good — O(n): join allocates once
result = " ".join(words)

f-strings are the modern formatting choice

name, score = "Alice", 98.6

# f-string — compiled to BUILD_STRING opcode, fastest
msg = f"{name} scored {score:.1f}"

# Older alternatives — slower or less readable
msg = "%s scored %.1f" % (name, score)
msg = "{} scored {:.1f}".format(name, score)
Learn it properly Strings

Keep practising

All Python questions

Explore further

Skip to content