1

So I have a helper function that is supposed to print out the internal nodes and leaves of a binary tree (unsorted). I won't provide the code since I'm in a class, but I can tell you that I have coded it up and it works for the first node I throw in there:

def helper(root, internals=[], leaves=[]):
    #function code here...
>>> helper(node)
    ([13, 14, 27], [10, 11, 12, 17, 19])

which is the correct output, as far as I know. However, when I call the same function again on another node, the output is overwritten into the previous one:

>>> helper(pen)
    ([13, 14, 27, 6, 8, 14], [10, 11, 12, 17, 19, 2, 4, 10, 12])

which is incorrect, since the tree pen does not have the elements 13,14,27 or 10,11,12,17,19. Can someone explain what's going on here? I have to test my function for different cases without restarting the shell every single time. How do I fix this?

  • "I won't provide the code since I'm in a class, ..." - what you've done is IMO a better practice on SO. The details of the function itself are completely irrelevant to your problem, so it's actually better to leave them out anyway. – millimoose Mar 08 '13 at 00:28

1 Answers1

9

Default arguments are evaluated when the function definition is encountered, that is, when Python sees the def line. They are then bound to the function itself.

With mutable default arguments, the default arguments bound to the function may be changed, which leads to some rather surprising results.

The usual advice: use None as the default, and create the actual defaults as needed:

def foo(bar=None):
    if bar is None:
        bar = []
    ...
nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • 1
    This doesn't work, since my function is recursive. Everytime the function is called again, `bar` is assigned `None`, and the first `if` statement is always executed, so I end up with either an empty list or a list with 1 element. –  Mar 08 '13 at 00:43
  • Then you need to explicitly pass in the current bar, viz `foo(bar)`. – nneonneo Mar 08 '13 at 00:44
  • You mean I should explicitly pass in the argument when calling the function recursively? Damn your right. I'll try that out. Stupid of me. –  Mar 08 '13 at 00:46