Published on

13. Default mutable arguments

Authors

13. What would the output of this code be?

def f(a,list=[]):
    for i in range(a):
        list.append(i*i)
    print(list)

f(3)
f(2,[1,2,3])
f(2)

This is a classic Python interview problem that tests your understanding of default mutable arguments.


🔍 The Code:

def f(a, list=[]):
    for i in range(a):
        list.append(i*i)
    print(list)

f(3)
f(2, [1, 2, 3])
f(2)

📌 Key Concept:

In Python, default argument values (like list=[]) are evaluated only onceat function definition time, not each time the function is called.

This means that if you mutate a default argument (like appending to a list), the change persists across function calls.


🧠 Let's go line by line:

1. f(3)

  • list=[] → uses the default empty list.

  • range(3) → 0, 1, 2 → squares: 0, 1, 4

  • list becomes: [0, 1, 4]

  • Output:

    [0, 1, 4]
    

2. f(2, [1, 2, 3])

  • list is explicitly passed → [1, 2, 3]

  • range(2) → 0, 1 → squares: 0, 1

  • list becomes: [1, 2, 3, 0, 1]

  • Output:

    [1, 2, 3, 0, 1]
    

3. f(2)

  • Uses the same default list as in the first call ([0, 1, 4])

  • range(2) → 0, 1 → squares: 0, 1

  • list becomes: [0, 1, 4, 0, 1]

  • Output:

    [0, 1, 4, 0, 1]
    

✅ Final Output:

[0, 1, 4]
[1, 2, 3, 0, 1]
[0, 1, 4, 0, 1]

💡 Best Practice:

Avoid mutable default arguments like this:

def f(a, list=None):
    if list is None:
        list = []
    for i in range(a):
        list.append(i*i)
    print(list)