Puzzling: local variable in recursive function made global?
Peter Otten
__peter__ at web.de
Thu Mar 26 15:32:29 EDT 2009
Daniel Oberski wrote:
> Hi Peter,
>
>> Plus, it works as expected (read: modifies the argument) if you
>> explicitly pass an empty list to the function...
>
> That is not so. The reason is given by Andrew Cooke in this thread.
>
> I would "expect" that when function calls lower in the recursion
> hierarchy return, the object is not changed from the point of view of the
> higher-order calls. This is expectation is mistaken because it is "the
> same frickin object" as Andrew said. One thing that goes wrong for
> example is the last unit test given in the program.
>
> This will happen even if an empty list is explicitly passed in the
> initial call...
As someone who knows Python I would expect that a function like
>>> def append(item, items=None):
... if items is None:
... items = []
... items.append(item)
... return items
...
always modifies the list argument:
>>> a = []
>>> append("x", a)
['x']
>>> a # a is modified
['x']
>>> b = ["x"]
>>> append("x", b)
['x', 'x']
>>> b # b is modified
['x', 'x']
I would be surprised by the behaviour of Andrew's variant:
>>> def append(item, items=None):
... items = items or []
... items.append(item)
... return items
...
>>> a = []
>>> append("x", a)
['x']
>>> a # a is left alone
[]
>>> b = ["x"]
>>> append("x", b)
['x', 'x']
>>> b # but b is not
['x', 'x']
This is why I prefer a test for the None sentinel over the boolean test.
Peter
More information about the Python-list
mailing list