>>> def fun(l=[]):
... l.append(1)
... print(l)
...
>>> fun()
[1]
>>> fun()
[1, 1]
>>> fun([])
[1]
>>> fun()
[1, 1, 1]
>>>
The second output is as expected, explained by - "A new list is created once when the function is defined, and the same list is used in each successive call." (source: https://docs.python-guide.org/writing/gotchas/).
But when an empty list is explicitly passed as an argument, the function's list should be reset to [], and the last output should be [1, 1] instead of [1, 1, 1].
From the same documentation.
Python’s default arguments are evaluated once when the function is defined, not each time the function is called (like it is in say, Ruby). This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.
To confirm this you can print the id
of the default argument. Default argument uses same list object for all future calls to the function. But where as fun([])
pass a new list object to l
(Hence does not uses the value of default argument)
>>> def fun(l=[]):
... l.append(1)
... print(l, f"id={id(l)}")
...
>>> fun()
[1] id=4330135048
>>> fun()
[1, 1] id=4330135048
>>> fun([])
[1] id=4330135944
>>> fun()
[1, 1, 1] id=4330135048