Python / Core Python Fundamentals Interview Questions
What is the mutable default argument trap in Python and how do you fix it?
One of Python's most notorious gotchas: default argument values are evaluated once at function definition time, not each time the function is called. If that default is a mutable object like a list or dict, every call that uses the default shares the same object, producing surprising accumulated state.
# BUG: the list is created once and shared across calls def add_item(item, collection=[]): collection.append(item) return collection print(add_item('a')) # ['a'] â looks fine print(add_item('b')) # ['a', 'b'] â surprise! shared default print(add_item('c')) # ['a', 'b', 'c']
The standard fix is to use None as the default and create a fresh object inside the function body:
def add_item(item, collection=None): if collection is None: collection = [] # fresh list on every call collection.append(item) return collection print(add_item('a')) # ['a'] print(add_item('b')) # ['b'] â independent
This issue only affects mutable objects (lists, dicts, sets, custom objects). Immutable defaults like integers, strings, and tuples are safe because they cannot be modified in place. You can inspect the current value of a function's defaults at runtime via function.__defaults__, which makes the problem visible: you will see the accumulated list growing there.
More Related questions...