1

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

def stackdemo(stack=[]):
  stack.append('q')
  return stack

stackdemo()
print stackdemo()

returns ['q','q'], whereas

stackdemo([])
print stackdemo([])

with the same function returns just ['q'], as expected.

Why does Python appear to reuse the array if the default is used? Am I missing something?

Community
  • 1
  • 1
Dragon
  • 2,017
  • 1
  • 19
  • 35

2 Answers2

3

A list is a mutable object. From doc:

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.

Do it with None:

def stackdemo(stack=None):
    if stack is None:
        stack = []
    stack.append('q')
    return stack

stackdemo()
print stackdemo()
eumiro
  • 207,213
  • 34
  • 299
  • 261
  • one-liner, clearer version of the `if` block: `stack = stack or []` – JCotton Feb 29 '12 at 20:08
  • @JCotton - this is wrong. Imagine calling `stackdemo(l)` with `l = []` defined before (and used elsewhere). – eumiro Mar 01 '12 at 08:09
  • you are right, though the one-liner may work in the OP's situation. It'd also be wrong with `stackdemo(mystr)` with `mystr=""` or other False values like that. It depends on the use and meaning of the `stack` variable. If a value of None has separate meaning or the variable could hold other valid-but-False values, then there is no substitute for the explicit `is None` check. – JCotton Mar 01 '12 at 16:41
1

In Python variables are passed by object reference, not by value.

This means that in this case you are modifying the stack=[] variable.

If you want to avoid this behaviour, than you have to generate the variable within the function since it will be generated on runtime in that case.

def stackdemo(stack=None):
    if stack is None:
        stack = []
    ...
Wolph
  • 78,177
  • 11
  • 137
  • 148
  • 1
    The first line is not actually right. Read [this](http://effbot.org/zone/call-by-object.htm) – JBernardo Dec 19 '11 at 16:43
  • @JBernardo: it is correct but depends on your definition of value. Since I left out the "object" part it might be a bit unclear. I'll clarify it a bit :) – Wolph Dec 19 '11 at 17:02