8

Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument

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

print(f(1, [1, 2]))
print(f(1))
print(f(2))
print(f(3))

I wonder why the other f(1), f(2), f(3) has not append to the first f(1, [1,2]). I guess the result should be :

[1, 2, 1]
[1, 2, 1, 1]
[1, 2, 1, 1, 2]
[1, 2, 1, 1, 2, 3]

But the result is not this. I do not know why.

Community
  • 1
  • 1
stardiviner
  • 1,090
  • 1
  • 22
  • 33
  • 1
    @Closevoters: as evident from his example, he does expect the default argument to change, so no, not a duplicate whatsoever. – georg Mar 27 '12 at 10:06

2 Answers2

7

There are two different issues (better to called concepts) fused into one problem statement.

The first one is related to the SO Question as pointed by agh. The thread gives a detailed explanation and it would make no sense in explaining it again except for the sake of this thread I can just take the privilege to say that functions are first class objects and the parameters and their default values are bounded during declaration. So the parameters acts much like static parameters of a function (if something can be made possible in other languages which do not support First Class Function Objects.

The Second issue is to what List Object the parameter L is bound to. When you are passing a parameter, the List parameter passed is what L is bound to. When called without any parameters its more like bonding with a different list (the one mentioned as the default parameter) which off-course would be different from what was passed in the first call. To make the case more prominent, just change your function as follow and run the samples.

>>> def f(a, L=[]):
        L.append(a)
        print id(L)
        return L

>>> print(f(1, [1, 2]))
56512064
[1, 2, 1]
>>> print(f(1))
51251080
[1]
>>> print(f(2))
51251080
[1, 2]
>>> print(f(3))
51251080
[1, 2, 3]
>>> 

As you can see, the first call prints a different id of the parameter L contrasting to the subsequent calls. So if the Lists are different so would be the behavior and where the value is getting appended. Hopefully now it should make sense

jamylak
  • 128,818
  • 30
  • 231
  • 230
Abhijit
  • 62,056
  • 18
  • 131
  • 204
0

Why you wait that's results if you call function where initialize empty list if you dont pass second argument?

For those results that you want you should use closure or global var.

Denis
  • 7,127
  • 8
  • 37
  • 58