Skip to main content
Back to Python Coding

Python Coding · Reading Functions and Notebooks

Mutable Default Arguments

The one idea: A default like an empty list is created once, when the function is first defined, and then shared by every call — so the function quietly remembers past calls, and your metrics double every time you re-run the cell. You can spot it in one glance at the def line, and the correct fix uses None instead.
⚠️ The trap: Re-running the same cell over the same data just recomputes the same numbers. That feels right and it's wrong. When a helper has a =[] (empty-list) or ={} (empty-dictionary) default, that container is built once and reused by every call, so each re-run appends to it again and your totals silently double — and they look perfect after a kernel restart, which is exactly why it slips through.

This is one specific Python landmine: a function that gives different answers each time you call it with the same inputs. In notebooks it has a signature crime — metrics that double every time you re-run a cell. You'll learn to spot it in one glance at a def line.

The bug in its purest form

def collect(value, results=[]):
    results.append(value)
    return results

collect(10)   # [10]
collect(20)   # [10, 20]   ← where did the 10 come from?

The second call never mentioned 10, yet there it is. Here's the mechanism, and it's the whole lesson:

A default value is evaluated once — when the def statement runs — not once per call. That [] created one single list at definition time, and every call that omits results gets that same list. The first call appends 10 to it. The second call…

Keep reading: Mutable Default Arguments

Unlock the full Python Coding track — every lesson, the AI tutor, and full mock assessments.

  • Full lesson content
  • AI tutor for this section
  • Practice questions