0

the two pieces of code below produce different outputs.

def f1(x= []):
    x.append(1)
    return x

print(f1())
print(f1())

Output is:

[1]
[1, 1]

And for the second function:

def f2(x=0):
    x+=1
    return x

print(f2())
print(f2())

Output is:

1
1

Now I know this is because "1" is int type and is immutable (same as if I had used a tuple). What I'm trying to understand is how does this logic work. At the start of both functions you are in the namespace of the respective function, and x has a assigned object to it. How come only in the second case it gets reassigned to "0"? Thanks.

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
ste_kwr
  • 820
  • 1
  • 5
  • 21
  • 2
    https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument – ktb Aug 03 '18 at 04:21
  • It does not get reassigned in the second case. The initial value is never changed, only locally replaced. By the time it runs again, the value is still the same. That‘s what immutability means. – MisterMiyagi Aug 03 '18 at 04:24
  • Thanks, this was helpful. Does this mean that the argument name "x" has no meaning here? Because at the end of the first run in both the cases the name "x" points(locally) to [1] or "1" respectively. If the name is immaterial, what is holding/pointing to this value of "0"? I also read through the other threads, still feel some clarification is needed here. – ste_kwr Aug 03 '18 at 04:27
  • @ste_kwr Lists in Python are bound to variables by reference, so in the first one `l` holds a pointer to the list. `.append()` mutates the list and even after the function ends `l` still points to that mutated list. While in the second function `+=` doesn't actually mutate the reference to the `1` object held by `l`, but rebind's that function's `l` variable to a new object `3`. The reference to the `1` held by the function isn't changed. While in the first one it is. Sorry this was marked as a duplicate, or I'd give a more in-depth explanation. – ktb Aug 03 '18 at 13:03
  • Hi, I fully understand that 'x' here is bound to a new object. My confusion is how is the function referencing the "0"? Is it not through the name "x"? – ste_kwr Aug 04 '18 at 21:49

0 Answers0