1

I was just playing with python list and I found strange behavior.

Here is my code.

def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

Output :

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

What I expect to believe is that list 3 output can contain 10 with 'a' as 10 was already in list variable of function argument when we called list1=extendList(10) (because expressions in default arguments are calculated when the function is defined, not when it’s called.) But how come 'a' gets appended to list1 as we are not calling it second time.

Pawan
  • 4,249
  • 6
  • 27
  • 32
  • A very popular gotcha, known as [mutable default argument](http://docs.python-guide.org/en/latest/writing/gotchas/). – bereal Apr 06 '15 at 17:55

1 Answers1

0

From the Python documentation:

Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:

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

print f(1) # [1]
print f(2) # [1, 2]
print f(3) # [1, 2, 3]
Malik Brahimi
  • 16,341
  • 7
  • 39
  • 70
  • but these are function calls their return value gets appended for sure, I am talking about lists, how come once created list (list1) gets appended without doing anything on it? – Pawan Apr 06 '15 at 17:58
  • As the stated above, the passed arguments are accumulated because you specified a default argument with a mutable object, which is a list. – Malik Brahimi Apr 06 '15 at 18:00
  • @Pawan `list1` is not created, it's assigned a reference to the previously created default list, which is later being appended to. – bereal Apr 06 '15 at 18:30