Ch. 9 · Python

Python Mutable Defaults and Shared State

Python Mutable Defaults and Shared State. Learn the reasoning, a practical example, common mistakes and an interview exercise.

~2 min readbeginnerupdated Oct 3, 2026

Default argument objects are evaluated when the function is defined, not freshly on each call. Mutable defaults can therefore share state across calls.

Before you start

You should know Python functions, collections and exceptions. Use a small isolated script or interactive session to trace the example. Pay attention to when objects are created and when work executes; iteration, binding and mutation can happen at different points in a program.

The practical goal is to reason through this situation: A function appending to a default list retains earlier items. Read the walkthrough first, then try the interview exercise before opening its answer. The important part is explaining the decision and its consequences, rather than remembering a definition alone.

Step-by-step walkthrough

Step 1: Locate object creation

Default argument objects are created when the function definition executes.

Step 2: Trace consecutive calls

Appending during one call changes the list reused by the next call.

Step 3: Create per-call state

Use None as a sentinel and allocate inside the function when omitted.

Worked scenario

A function appending to a default list retains earlier items.

def append_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items
print(append_item('a'))  # ['a']
print(append_item('b'))  # ['b']
python

A supplied list is still modified intentionally; independent omitted arguments do not share state.

Common mistake

Assuming every call receives a new list produces cross-request contamination.

Verify the behavior

Test omitted input twice and an explicitly supplied empty list; distinguish intended caller mutation from accidental sharing.

Interview exercise

Create an independent optional list.

Answer and reasoning

Default to None and create a new list inside the function when no list is supplied.

Continue learning

Compare the scenario with the Python interview questions and test your understanding with the Python MCQs. For terminology and implementation details, consult the reference material.

More in Python

read ✓Python · hard

Python asyncio.gather and Timeouts

Run coroutines concurrently with asyncio.gather, enforce timeouts, and handle partial failures and cancellation correctly.

~2 min readread →
read ✓Python · mid

Python Bounded Async Worker Queues

Use asyncio.Queue and a fixed worker pool to bound pending work. Trace backpressure, shutdown and failure ownership.

~3 min readread →
read ✓Python · mid

Python Asyncio and Blocking Functions

Python Asyncio and Blocking Functions. Learn the reasoning, a practical example, common mistakes and an interview exercise.

~2 min readread →
esc