たとえば、次のステートメントがある場合:
if( foo1 or foo2)
...
...
foo1がtrueの場合、python foo2の状態を確認しますか?
はい、Pythonはブール条件を遅延評価します。
docs say 、
式xおよびyは、最初にxを評価します。 xがfalseの場合、その値が返されます。それ以外の場合、yが評価され、結果の値が返されます。
式xまたはyは最初にxを評価します。 xがtrueの場合、その値が返されます。それ以外の場合、yが評価され、結果の値が返されます。
and
or
はレイジーです
&
|
は怠notではない
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」の両方が印刷されます。
これは技術的に怠zyな評価ではなく、ショートサーキットのブール式です。
遅延評価には多少異なる意味があります。たとえば、真の遅延評価ではおそらくこれが可能になります
def foo(arg) :
print "Couldn't care less"
foo([][0])
しかしPythonではありません。
Pythonは、ブール引数である「エコー」という点でも優れています。たとえば、or条件は、最初の「真の」引数または最後の引数(すべての引数が「偽」の場合)を返します。 and条件は逆を行います。
したがって、「エコー引数」ブール値は
2および[]および1
[]に評価され、かつ
[]または1または2
1と評価されます
はい、Pythonは遅延評価されるため、foo2
はチェックされません。
キーが存在するかどうかわからない場合、辞書のようなオブジェクトからアイテムを取得するために常にこれを使用します。
if 'key' in mydict and mydict['key'] == 'heyyo!':
do_stuff()
詳細な説明については、@ unutbuの回答を参照してください。
短絡しているのは、実際に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
短いデモでは、次の時間差を比較します
all(xrange(1,1000000000))
そして
any(xrange(1,1000000000))
All()はすべての単一の値をチェックする必要がありますが、any()は最初のTrueが見つかった後にあきらめることができます。したがって、ジェネレーターであるxrangeは、評価者が完了するとすぐにものを生成することをあきらめます。このため、allは大量のRAMを消費し、時間がかかりますが、anyはほんの数バイトを使用して即座に戻ります。