CodeOath
← All posts
Python70 min total · 18 parts

Python Fundamentals for Interviews: Data Structures, Comprehensions, and Gotchas

Contents — Part 8 of 18: The Mutable Default Argument Bug
Part 8 of 18 · ~1 min

The Mutable Default Argument Bug

This one has caught nearly every Python developer at least once, and is arguably the single most common Python "gotcha" interview question:

def add_item(item, basket=[]):   # DANGER
    basket.append(item)
    return basket

add_item("apple")   # ["apple"]
add_item("banana")  # ["apple", "banana"] — NOT a fresh list!

Default argument values are evaluated once, when the function is defined — not on every call. basket=[] creates one list object, shared across every call that doesn't pass its own basket. The same bug applies to any mutable default: {}, set(), or a custom mutable object. The fix:

def add_item(item, basket=None):
    if basket is None:
        basket = []
    basket.append(item)
    return basket

Immutable defaults (0, "", None, a tuple) are completely safe, precisely because there's no way to mutate them in place — every "danger" case involves a mutable default.