python boolean expression not "short-circuit"? [duplicate]
Asked Answered
C

2

10

For example:

def foo():
    print 'foo'
    return 1
if any([f() for f in [foo]*3]):
   print 'bar'

I thought the above code should output:

foo
bar

instead of :

foo
foo
foo
bar

Why ? how can I make the "short-circuit" effect ?

Cheeks answered 29/11, 2010 at 8:18 Comment(1)
Short answer: The [f() for f in [foo]*3] list comprehension executes and creates a list of f() return values before any() has a chance to evaluate them (and short-circuit).Pox
M
18

Deconstruct your program to see what is happening:

>>> [f() for f in [foo]*3]
foo
foo
foo
[1, 1, 1]
>>> 

You are already creating a list and passing to any and have printed it 3 times.

>>> any ([1, 1, 1])
True

This is fed to if statement:

>>> if any([1, 1, 1]):
...     print 'bar'
... 
bar
>>> 

Solution: Pass a generator to any

>>> (f() for f in [foo]*3)
<generator object <genexpr> at 0x10041a9b0>
Motet answered 29/11, 2010 at 8:22 Comment(1)
Great for python! what could be simpler than that !Cheeks
W
5

It's creating the list before passing it to any

try

def foo():
    print 'foo'
    return 1
if any(f() for f in [foo]*3):
   print 'bar'

this way only a generator expression is created, so only as many terms as necessary are evaluated.

Wold answered 29/11, 2010 at 8:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.