why are these not the same?

L

Lowell Kirsh

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)
 
F

Fredrik Lundh

Lowell said:
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?
def functionF(argString="abc", argList = None):
if argList is None: argList = []
...

def functionF(argString="abc", argList=None):
argList = argList or []
...

"is None" tests for None, "argList or" tests for a false value. None is
false, but many non-None objects are also false.

"should be avoided" sounds like overly zealous advice to me; use the
latter form if you understand it.

</F>
 
L

Lowell Kirsh

D'oh I should've caught that myself.

Thanks.

Fredrik said:
Lowell said:
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?

def functionF(argString="abc", argList = None):
if argList is None: argList = []
...

def functionF(argString="abc", argList=None):
argList = argList or []
...


"is None" tests for None, "argList or" tests for a false value. None is
false, but many non-None objects are also false.

"should be avoided" sounds like overly zealous advice to me; use the
latter form if you understand it.

</F>
 
D

Duncan Booth

Lowell said:
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:
if l is None: l = []
l.append(s)
return '*'.join(l)
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top