0

I was going through https://docs.python.org/3.5/tutorial/controlflow.html#default-argument-values. I modified the example there a little bit as below:

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

x = [8,9]
print(f(1,[6,7]))
print(f(2))
print(f(3))

The output I got was:

[6, 7, 1]
[4, 5, 2]
[4, 5, 2, 3]

Now, as per what I understood from the Python docs:

  1. The default values are evaluated at the point of function definition in the defining scope. So, L = [4,5]

  2. After the 1st call to f(), L = [6,7,1]. This is fine.

  3. What don't understand is output after 2nd call to f(). If L's value is shared between the calls to f(), then the output after 2nd function call should be [6,7,1,2]. L's value was shared between 2nd and 3rd call to f() but not between 1st and 2nd call.

2 Answers2

0

This is because each time you call f it performs L=x, as x is a default value for L on you argument list of f.

So every time it actually appends to x.

Israel Unterman
  • 13,158
  • 4
  • 28
  • 35
  • If that is the case, then output of 3rd call to f() should be [4,5,3]? Also, Pyhton docs say that "The default value is evaluated only once." –  Apr 06 '17 at 12:57
0

It's not that the value of L is shared, rather that the default value of L as defined when the function is created is shared. In this case that's the list that starts as [4, 5].

If you specify a different value for L when you call f (as you do in the first call) then that is what is used and it's not shared with other calls.

If you don't specify any value for L, then it uses the default value (as you'd expect), which is shared.

Anyway, in case it wasn't clear, don't use mutable default values. If you want some behaviour that can be conveniently done using mutable default values, do it manually. Even if the code is slightly longer, it will be more explicit, predictable, and readable.

Alex Hall
  • 34,833
  • 5
  • 57
  • 89