The list, x
, isn't initialized to the parameter default value each time the function is operated, but remains in the previous state and adds a new value.
That's how the function was executed 5 times, so it became [7, 7, 7, 7, 7]
.
However, the integer y appears to hold the default value. It has been run 5 times, but it continues to output 2
.
Why does y
finally output 2
instead of 6
when the function is executed 5 times?
I've already read this question, but it explains where the list binds to a function. But I wonder why the principle does not apply to integer default parameters.
def foo(x=[],y=1):
x.append(7)
y += 1
return x, y
print(foo())
print(foo())
print(foo())
print(foo())
print(foo())
([7], 2)
([7, 7], 2)
([7, 7, 7], 2)
([7, 7, 7, 7], 2)
([7, 7, 7, 7, 7], 2)
Int's are immutable, lists are not. When you assign a default value to a parameter you are assigning a reference to that value. Performing y += 1
actually creates a new reference and assigns it to y
, it does not change the value of the old reference. When you mutate the container you are not changing the reference. Example:
y = 1
x = y
# This will be true as they have the same reference
print(x is y) # True
y += 1
# This will be false as the reference to y has been changed
print(x is y) # False
y = []
x = y
# This will be true as they have the same reference
print(x is y) # True
y.append(1)
# This will still be true, the reference to the container remains the same.
print(x is y) # True