web-dev-qa-db-ja.com

Python ifの条件を遅延評価しますか?

たとえば、次のステートメントがある場合:

if( foo1 or foo2)
    ...
    ...

foo1がtrueの場合、python foo2の状態を確認しますか?

56
ogama8

はい、Pythonはブール条件を遅延評価します。

docs say

式xおよびyは、最初にxを評価します。 xがfalseの場合、その値が返されます。それ以外の場合、yが評価され、結果の値が返されます。

式xまたはyは最初にxを評価します。 xがtrueの場合、その値が返されます。それ以外の場合、yが評価され、結果の値が返されます。

75
unutbu

andorはレイジーです

&|は怠notではない

24
Eric Wang

Pythonの遅延は、次のコードで証明できます。

def foo():
    print('foo')
    return False

def bar():
    print('bar')
    return False

foo() and bar()         #Only 'foo' is printed

一方、

foo() or bar()

「foo」と「bar」の両方が印刷されます。

10
Erik Veloso

これは技術的に怠zyな評価ではなく、ショートサーキットのブール式です。

遅延評価には多少異なる意味があります。たとえば、真の遅延評価ではおそらくこれが可能になります

def foo(arg) :
    print "Couldn't care less"

foo([][0])

しかしPythonではありません。

Pythonは、ブール引数である「エコー」という点でも優れています。たとえば、or条件は、最初の「真の」引数または最後の引数(すべての引数が「偽」の場合)を返します。 and条件は逆を行います。

したがって、「エコー引数」ブール値は

2および[]および1

[]に評価され、かつ

[]または1または2

1と評価されます

5
Pete Cacioppi

はい、Pythonは遅延評価されるため、foo2はチェックされません。

キーが存在するかどうかわからない場合、辞書のようなオブジェクトからアイテムを取得するために常にこれを使用します。

if 'key' in mydict and mydict['key'] == 'heyyo!':
    do_stuff()

詳細な説明については、@ unutbuの回答を参照してください。

2
jdotjdot

短絡しているのは、実際にor部分です:

>>> 1 or 1/0  #also 0 and 1/0
1
>>> 0 or 1/0  #also 1 and 1/0

Traceback (most recent call last):
  File "<pyshell#1240>", line 1, in <module>
    0 or 1/0
ZeroDivisionError: integer division or modulo by zero
1
dansalmo

短いデモでは、次の時間差を比較します

all(xrange(1,1000000000))

そして

any(xrange(1,1000000000))

All()はすべての単一の値をチェックする必要がありますが、any()は最初のTrueが見つかった後にあきらめることができます。したがって、ジェネレーターであるxrangeは、評価者が完了するとすぐにものを生成することをあきらめます。このため、allは大量のRAMを消費し、時間がかかりますが、anyはほんの数バイトを使用して即座に戻ります。

1
J.J