pythondefault-parameters

Workaround Mutable Default Arguments in Python


Going through the python documentation, I came across below.

Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

This will print

[1]
[1, 2]
[1, 2, 3]

If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

Now as I understand, the first example behaves the way it does, because L binds to an empty list at the definition, and hence any changes to that (on multiple calls) will reflect in the original list.

And hence, in the second example, we don't bind L to anything (i.e. None), and hence on multiple calls, we'll always get it set to None. So my question is why do we even need the if statement in the second example if L is None, wouldn't it always be true?


Solution

  • No, it wouldn't always be true. None is the default argument for L, but it won't always be None. The function allows the caller to input their own list instead. If the if was removed, then L would always be replaced by an empty list, even if the caller tried to pass a different list to the function.