Course outline · 0% complete

0/27 lessons0%

Course overview →

Default values and the mutable default trap

lesson 2-2 · ~10 min · 5/27

Defaults are evaluated once

You already know default parameters: def greet(name="friend"). Here is the detail Python for Beginners skipped, and it causes real bugs: the default value is created once, when the def line runs, not on every call.

For numbers and strings that is harmless. For a mutable value like a list or dict, it means every call that uses the default shares the same object:

def add_item(item, bucket=[]):
    bucket.append(item)
    return bucket

Call it twice without passing a bucket and the second call finds the first call's item still sitting in the list. This trap genuinely ships to production, where a shared default list quietly leaks one request's data into the next, and it is one of the most common Python interview questions. Run the next example to see it happen.

Code exercise · python

Run this program and look closely at the second line. We never passed a list, yet "apple" is already in it.

The fix: a None sentinel

The standard pattern is to default to None (an immutable placeholder) and create the fresh list inside the function body, which runs on every call:

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

Now each default call gets its own new list. Remember the rule as: never use [], {}, or any mutable object as a default value. Every experienced Python interviewer asks about this.

Code exercise · python

Your turn. Fix log_event so each call without a target list gets a FRESH list. Use the None sentinel pattern. The output should show two independent single-item lists.

Quiz

Why is def f(x, seen=set()) dangerous?

Quiz

Which default values are safe to write directly in a def line?