After reading this thread, I also tried to get my hands dirty with default arguments. So, following is the same function having the mutable default argument:-
def foo(x = []):
x.append(1)
return x
As defined in the docs, the default value is evaluated only once when the function is defined.
So, upon executing this statement, print(foo(), foo(), foo())
, I expected the output to be like this: [1] [1, 1] [1, 1, 1]
Instead, this is what I actually got as an output:-
>>> print(foo(), foo(), foo())
[1, 1, 1] [1, 1, 1] [1, 1, 1]
The way the statement is executed (according to me) is that the 1st function call returns [1], the 2nd returns [1, 1] and the 3rd function call returns [1, 1, 1] but it's the 3rd function call return value only which is printed repeatedly.
Also, printing the same function return values as separate statements(as mentioned in that thread) gives expected result, i.e.,
>>> print(foo())
[1]
>>> print(foo())
[1, 1]
>>> print(foo())
[1, 1, 1]
So, why printing the same function return values together doesn't return the output the way it does when executed separately?
print(foo(), foo(), foo())
evaluates eachfoo()
in turn, but the call toprint()
only occurs once all calls tofoo()
have finished. Also each return fromfoo()
returns a reference to the same list. Soprint()
just prints the same thing three times. – quamranaprint(foo())
one at a time, it does output what you expect. I indeed suppose that in a combined print statement, all calls are executed first after which the list has value [1,1,1] which is then printed. – Ronald