9.14 Common Mistakes
The most common string bugs in Python -- expecting a method to mutate in place, mismatching find() and index() error behavior, off-by-one slicing errors, and O(n^2) concatenation in a loop.
Assuming a Method Mutates in Place
Every string method returns a new string — the original is never changed, since str is immutable (see 9.1 Introduction to Strings).
>>> s = "hello"
>>> s.upper() # returns a new string
>>> s # s itself is UNCHANGED
'hello'
>>> s = s.upper() # must reassign to actually keep the result
Confusing find() and index()
find() returns -1 when nothing matches; index() raises ValueError. Using the wrong one for the situation either silently produces a bogus -1 result or crashes unexpectedly.
>>> "hello".find("z") # no exception -- easy to silently misuse
-1
>>> "hello".index("z") # raises instead
Traceback (most recent call last):
ValueError: substring not found
Off-by-One Slicing Errors
Forgetting that stop in s[start:stop] is exclusive is one of the most common slicing bugs — s[0:5] gets 5 characters (indices 0–4), not 6.
O(n²) Concatenation in a Loop
Building a large string with += inside a loop looks harmless on small inputs but degrades badly at scale — see 9.11 Memory and Performance for why, and join() for the fix.
# Looks fine on 10 items, degrades badly on 100,000
result = ""
for line in lines:
result += line
Comparing Strings with is
Interning is a CPython implementation detail, not a guarantee — comparing with is can pass in a quick test and fail unpredictably on runtime-built strings.
>>> a = "hello"
>>> b = "".join(["h", "e", "l", "l", "o"])
>>> a == b # correct: compares content
True
>>> a is b # WRONG tool: compares identity, not guaranteed True
False
Quick Interview Answer
“The recurring string bugs share one root cause or another: forgetting immutability means a method’s return value must be captured (
s = s.upper(), not justs.upper()); mixing upfind()’s silent-1withindex()’sValueErrorproduces either a bogus result or an unexpected crash; forgetting slicing’sstopis exclusive causes off-by-one errors; building a large string with+=in a loop is O(n²) and only shows up as a real problem at scale; and comparing withisinstead of==relies on CPython’s interning, which isn’t a language guarantee.”
Common Mistakes
- Writing
s.strip()on a line and expectingsitself to be stripped afterward — the call must be assigned back:s = s.strip(). - Using
find()’s-1return value directly as an index without checking for it first, silently slicing from the end of the string instead of failing loudly. - Reaching for
+=string-building inside a loop that turns out to run over a large or unbounded number of iterations (a log file, an API pagination loop) — the O(n²) cost compounds fast.
Add More Questions to This Guide
Know a question that should be here? Share it and help the community!
Open Google Form