Why a mutable default argument leaks state in Python
A default argument in Python is evaluated once, when the function is defined, not each time it is called. If that default is a mutable list, every call that omits the argument shares the same list.
The quick answer
Do not use a mutable value like a list as a default argument. Default to None, then create a fresh list inside the function when no argument is supplied.
A minimal example
def record(label, history=[]):
history.append(label)
return historydef record(label, history=None):
if history is None:
history = []
history.append(label)
return historyIn the bugged version, calling the function twice without the optional argument appends to the same list, so results accumulate across calls. The None guard gives each call its own list.
How to debug it
- Call the function twice in a row without passing the optional argument.
- If the second result contains data from the first call, the default is shared.
- Look for a mutable default: a list, dict, or set in the signature.
- Replace it with None and build the container inside the function.
Common wrong fixes
- Clearing the list at the start of the function, which mutates a shared object others may hold.
- Copying the default inside the function but keeping the mutable default in the signature.
- Using a tuple default and then trying to append to it.
Limits of this guide
This is the classic mutable-default case. Related traps include mutable class attributes and shared caches. The challenge focuses on the default-argument version so the cause is unambiguous.
Authoritative references
Ready to try it?
Fix this bug in a free challengeRelated pages
The missing await bug in JavaScript async functions
A missing await makes JavaScript read a Promise as if it were the resolved value. See the failure, the one-line fix, and the wrong fixes to avoid.
Why a JOIN duplicates rows, and how to fix cardinality
A one-to-many JOIN multiplies rows, so a customer with several orders appears many times. Learn to diagnose cardinality and aggregate to the right grain.
Guides
Short debugging guides that each explain one common bug, show a minimal fix, and open a matching free challenge. Browse guides by language.