Practical technology learning
Python Mutable Defaults: Decide Whether Each Function Call Gets a Fresh List
A surprising second function call is often easier to understand than a long debugging session. This exercise asks who owns a list, when it is created and whether later calls are meant to share it. Use fictional study tags in a local Python file.
Start with an observable two-call example
Define collect(tag, tags=[]), append tag to tags, and return tags. Immediately print collect("loops"), then immediately print collect("files"). Predict both lines before running the file. The first line contains loops; the second contains loops and files.
Print each result immediately. If you save both returned references and display them only after both calls, the earlier reference also sees the later mutation. That is an extra observation about sharing, not evidence that the first call originally printed two tags.
Explain the lifetime precisely
Python evaluates a default expression when the function definition executes. Omitting the list argument therefore reuses the stored default object. A new call does not, by itself, create a replacement list. Restarting the file creates a new definition and can hide the repeated-call symptom.
Make independent calls intentional
Change the signature to collect(tag, tags=None). Inside, use if tags is None: tags = [], then append and return. Two omitted-argument calls now create independent collections. A default of None is appropriate here because this exercise does not need None to mean a separate, valid collection value.
Test caller-owned data separately
Create supplied = [] and pass it explicitly. The None check preserves that list, and appending changes the caller-owned object. If the desired contract is non-mutating, make a deliberate copy instead and document what depth of copying the data requires. An empty list is a valid input, so do not silently replace it merely because it is false in a condition.
Keep a useful review note
- Record the exact call order and immediate outputs.
- Mark omitted arguments separately from explicitly supplied lists.
- State whether mutating a supplied list is allowed.
- Repeat the sequence without restarting the interpreter between calls.
Connect the exercise to further study
Functions and lists appear in the Mango Engineers Python learning path. Jaipur learners can use this practice task to discuss state ownership with visible evidence. Keep the short file and call sequence together so someone else can repeat the observation.