TL; DR
まず、2つの論理演算子and
との2つの動作を要約しor
ます。これらのイディオムは、以下の議論の基礎を形成します。
and
ファルシーがある場合は最初の値を返し、そうでない場合は式の最後の値を返します。
or
存在する場合は最初のTruthy値を返し、そうでない場合は式の最後の値を返します。
動作もdocs、特に次の表にまとめられています。
オペランドに関係なくブール値を返す唯一の演算子はnot
演算子です。
「真実性」および「真実性」の評価
ステートメント
len(args) and max(args) - min(args)
ある非常に ニシキヘビ「と言った場合の方法簡潔な(と、おそらくあまり読み)args
空にする、結果を返さないでmax(args) - min(args)
、そうでない場合はリターンが」0
。一般に、if-else
式のより簡潔な表現です。例えば、
exp1 and exp2
(大まかに)変換する必要があります:
r1 = exp1
if r1:
r1 = exp2
または、同等に、
r1 = exp1 if exp1 else exp2
同様に、
exp1 or exp2
同等です、
r1 = exp1
if not r1:
r1 = exp2
どこexp1
とexp2
任意のPythonオブジェクト、またはいくつかのオブジェクトを返す式です。ここでの論理演算子and
とor
演算子の使用法を理解するための鍵は、それらが操作やブール値を返すことに制限されていないことを理解することです。真実値を持つすべてのオブジェクトをここでテストできます。これにはint
、str
、list
、dict
、tuple
、set
、NoneType
、およびユーザー定義オブジェクトを。短絡回路のルールも引き続き適用されます。
しかし、真実とは何ですか?
条件式で使用した場合のオブジェクトの評価方法を指します。@Patrick Haughはこの投稿で真実性をうまくまとめています。
次の「偽」を除いて、すべての値は「真実」と見なされます。
None
False
0
0.0
0j
Decimal(0)
Fraction(0, 1)
[]
- 空っぽ list
{}
- 空っぽ dict
()
- 空っぽ tuple
''
- 空っぽ str
b''
- 空っぽ bytes
set()
- 空っぽ set
- 空の
range
ようなrange(0)
- オブジェクト
obj.__bool__()
戻り値 False
obj.__len__()
戻り値 0
「真実の」値は、if
or while
ステートメントによって実行されるチェックを満たします。「真実」と「虚偽」を使用して、bool
値True
とを区別し
ますFalse
。
どのand
作品
OPの質問を、これらのインスタンスでこれらの演算子がどのように使用されるかについての議論のセグエとして構築します。
定義のある関数を考える
def foo(*args):
...
ゼロ以上の引数のリストで最小値と最大値の差を返すにはどうすればよいですか?
最小値と最大値を見つけるのは簡単です(組み込み関数を使用してください!)。ここでの唯一の障害は、引数リストが空である可能性があるコーナーケースを適切に処理することです(たとえば、を呼び出すfoo()
)。and
演算子のおかげで、両方を1行で行うことができます。
def foo(*args):
return len(args) and max(args) - min(args)
foo(1, 2, 3, 4, 5)
# 4
foo()
# 0
ためand
に使用される最初である場合、第二の発現も評価されなければなりませんTrue
。最初の式が真であると評価された場合、戻り値は常に2番目の式の結果であることに注意してください。最初の式がFalsyと評価された場合、返される結果は最初の式の結果です。
上記の関数では、Ifがfoo
1つ以上の引数を受け取った場合、len(args)
は0
(正の数)より大きいため、返される結果はになりmax(args) - min(args)
ます。引数が渡されない場合OTOH、len(args)
ある0
Falsyである、と0
返されます。
この関数を作成する別の方法は次のとおりです。
def foo(*args):
if not len(args):
return 0
return max(args) - min(args)
または、より簡潔に、
def foo(*args):
return 0 if not args else max(args) - min(args)
もちろん、これらの関数はいずれも型チェックを実行しないため、提供された入力を完全に信頼しない限り、これらの構造の単純さに依存しないでください。
どのor
作品
or
同様の方法での作業を考案した例で説明します。
定義のある関数を考える
def foo(*args):
...
foo
すべての数値を返すにはどのように完了し9000
ますか?
or
ここではコーナーケースの処理に使用します。次のように定義しますfoo
。
def foo(*args):
return [x for x in args if x > 9000] or 'No number over 9000!'
foo(9004, 1, 2, 500)
# [9004]
foo(1, 2, 3, 4)
# 'No number over 9000!'
foo
リストをフィルタリングして、を超えるすべての数値を保持します9000
。そのような数値が存在する場合、リスト内包の結果は空ではないリストであり、Truthyであるため、返されます(ここでの短絡)。そのような数が存在しない場合、リストcompの結果[]
はFalsyになります。したがって、2番目の式が評価され(空でない文字列)、返されます。
条件文を使用すると、この関数を次のように書き直すことができます。
def foo(*args):
r = [x for x in args if x > 9000]
if not r:
return 'No number over 9000!'
return r
以前と同様に、この構造はエラー処理に関してより柔軟です。
and
(およびor
)は、ブール値の操作やブール値の返却に限定されません。