Pythonにおける『and』と『or』の動作
Pythonの『and』と『or』の動作は, 他の言語と少し違う変わった動作をするのでそれについてメモ.
一般的な『and』と『or』の動作
bool型(True, またはFalse)の変数A, Bとしたときに,
A | B | A and B | A or B |
---|---|---|---|
True | True | True | True |
True | False | False | True |
False | True | False | True |
False | False | False | False |
に, なります. ここでのポイントは, 『AとBはBool型のみである』ということです.
Pythonにおける『and』と『or』の動作①
では, Pythonではどのような動作になるか, まず入力の条件から書きます. 『AとBの型についての制限はありません』.
何を言っているのかと思うと思いますが, Pythonでのand
,or
はAとBの型についての制限がないのです.
これには, and
とor
がそれぞれ行っている処理が深くかかわっています.
and の処理
Pythonのand
は以下のような処理を行います.
A and B
と書くとき, 第一引数A(第一引数) が偽なら A(第一引数), そうでなければ B(第二引数)
コードの形で記述すると以下のようになります.
if not bool(A): return A else: return B
2種類の返値を見るとわかるように, 引数のどちらかをそのまま返しているのがわかると思います.
ではここに示されているbool(A)
では何が起こっているのでしょう.
Bool の処理
bool
は基本的にどんなものでも真偽値判定を行ってくれます.
ポイントとなるのが, 偽と見なされる以下の値達です.
- None
- False
- 数値型におけるゼロ ( ex. 0, 0.0)
- 空のシーケンス ( ex. '', (), [] )
- 空のマッピング ( ex. {} )
- ユーザ定義クラスのインスタンスで, bool() , len()メソッドを定義していて, 整数 0 または bool値 False を返すとき
逆にこれ以外のケースは全て真になります.
or の処理
Pythonのor
は以下のような処理を行います.
A or B
と書くとき, 第一引数A(第一引数) が偽なら B(第二引数), そうでなければ A(第一引数)
コードの形で記述すると以下のようになります.
if not bool(A): return B else: return A
見た目はandと逆の構造になっています.
Pythonにおける『and』と『or』の動作②
上記のBool
の性質を理解したうえで, Pythonの場合のand
の入出力の対応表を書くと以下の通りになります.(ちょっとだけ書き方自体も違うので読むとき注意)
それぞれのA,BをBool
にかけたときにどんな値が帰ってくるかも書いておきました.
これを見るともともと真偽値表と同じ形になっていて, 正しくand
, or
として機能しているのがわかると思います.
bool(A) | bool(B) | A and B | A or B |
---|---|---|---|
True | True | B(bool(B)->True) | A(bool(A)->True) |
True | False | B(bool(B)->False) | A(bool(A)->True) |
False | True | A(bool(A)->False) | B(bool(B)->True) |
False | False | A(bool(A)->False) | B(bool(B)->False) |
おまけ:サンプルコード
これの検証に書いたしょぼいコードですが置いておきます. 実行結果も合わせてどうぞ.
A = ["abc", ""] B = ["xyz", ""] for a in A: for b in B: print( "A(" + a + ") or B(" + b + ") -> " + (a or b)) for a in A: for b in B: print( "A(" + a + ") and B(" + b + ") -> " + (a and b))
A(abc) or B(xyz) -> abc A(abc) or B() -> abc A() or B(xyz) -> xyz A() or B() -> A(abc) and B(xyz) -> xyz A(abc) and B() -> A() and B(xyz) -> A() and B() ->