Lessons · Python · the def f(x=[]) trap
The default argument that remembers
A default value is created once, when the function is defined. If it is a list or dict, every call shares the same one.
Hone is a place to practise programming. This is one of its lessons, written out in full and free to read without an account.
What it is for
This is a genuine production bug: a cache or history that quietly carries data from one request into the next. It passes every simple test and fails under real use.
How to think about it
Is this default a list, dict or set? Never use a list, dict or set as a default. Use None, and inside the function write 'if items is None: items = []'.
Worked example
def add(item, items=None):None is immutable; safe as a default.
if items is None:The first call with no list...
items = []...gets a fresh one, every time.
items.append(item); return itemsNow two calls do not share a list.
Your turn
Fix the default so calls do not share state.
def log(msg, history=):
if history is None:
history = []
history.append(msg)
return historySolve one with the tests running
The trap
def f(items=[]) looks right and works the first time. The second call finds the first call's items still there.