булево выражение python не "короткое замыкание"? - PullRequest
10 голосов
/ 29 ноября 2010

Например:

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

Я думал, что приведенный выше код должен выводить:

foo
bar

вместо:

foo
foo
foo
bar

Почему?как сделать эффект "короткого замыкания"?

Ответы [ 2 ]

18 голосов
/ 29 ноября 2010

Деконструируйте вашу программу, чтобы увидеть, что происходит:

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

Вы уже создаете список и переходите к любому и распечатали его 3 раза.

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

Это подается в оператор if:

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

Решение: передать генератор любому

>>> (f() for f in [foo]*3)
<generator object <genexpr> at 0x10041a9b0>
5 голосов
/ 29 ноября 2010

Он создает список перед передачей его любому

try

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

таким образом создается только выражение генератора, поэтому оценивается только столько терминов, сколько необходимо.

...