why are these not the same?
Duncan Booth
duncan.booth at invalid.invalid
Thu Jan 20 05:06:01 EST 2005
Lowell Kirsh wrote:
> On a webpage (see link below) I read that the following 2 forms are not
> the same and that the second should be avoided. They look the same to
> me. What's the difference?
>
> Lowell
>
> ----
>
> def functionF(argString="abc", argList = None):
> if argList is None: argList = []
> ...
>
> def functionF(argString="abc", argList=None):
> argList = argList or []
> ...
>
> http://www.ferg.org/projects/python_gotchas.html (number 5)
If functionF mutates its argument then these two will give different and
possibly unexpected results. I suspect this is what they are hinting at:
>>> def f1(s="abc", l=None):
if l is None: l = []
l.append(s)
return '*'.join(l)
>>> def f2(s="abc", l=None):
l = l or []
l.append(s)
return '*'.join(l)
>>> f1('foo', ['bar'])
'bar*foo'
>>> f2('foo', ['bar'])
'bar*foo'
>>> f1('foo', [])
'foo'
>>> f2('foo', [])
'foo'
So far the functions appear to operate identically. But:
>>> myList = []
>>> f1('foo', myList)
'foo'
>>> myList
['foo']
>>> myList = []
>>> f2('foo', myList)
'foo'
>>> myList
[]
It looks as though f1 mutates its argument but f2 doesn't, until you try:
>>> f2('foo', myList)
'bar*foo'
>>> myList
['bar', 'foo']
>>>
>>>
So f2 mutates a non-empty list but leaves an empty list unchanged which is
probably not what you intend and certainly confusing.
More information about the Python-list
mailing list