はじめに
Qiita初投稿の新米エンジニアです。
仕事でちょこちょこpythonを使うようになり、ある程度コーディングもしていたのですが、恥ずかしながらandやorの挙動について勘違いがあったのでまとめました。
どういうことか
こういうこと。
>>> 'foo' and ''
''
>>> 'foo' or ''
'foo'
>>> 'foo' and 'bar'
'bar'
>>> 'foo' or 'bar'
'foo'
andやorはboolを返すものだと思っていましたが、どうやらそうではない。
'foo' and '' → ''
'foo' or '' → 'foo'
あたりは何となくわかりますが、なぜ
'foo' and 'bar' → 'bar'
'foo' or 'bar' → 'foo'
のようにandとorで結果が異なるのか。
そのあたりの挙動について、ドキュメントのブール演算子の項を参考に以下にまとめました。
and演算子、or演算子の評価ロジック
x and yもx or yも、基本的には以下の評価を行い、結果を返す。
-
xの真偽値によって式全体の真偽値が確定する場合(yの真偽値に関わらず式全体の真偽値が確定する場合)はxを返す。 -
xの真偽値だけでは式全体の真偽が確定しない場合(yの真偽値を見て初めて式全体の真偽値が確定する場合)はyを返す。
※なお、not演算子については、戻り値はいつでもboolとなります。
冒頭の4つの式についてそれぞれ上記のロジックに当てはめると、
-
'foo' and ''
→'foo'は空文字でないので真。式全体の真偽が確定しないため''を返す。 -
'foo' or ''
→'foo'は空文字でないので真。式全体の真偽が確定するため'foo'を返す -
'foo' and 'bar'
→'foo'は空文字でないので真。式全体の真偽が確定しないため'bar'を返す。 -
'foo' or 'bar'
→'foo'は空文字でないので真。式全体の真偽が確定するため'foo'を返す
つまり'foo' and 'bar'と'foo' or 'bar'で結果の異なる理由としては、'foo'の評価の時点で結果が確定するか'bar'の評価で確定するかの違い。
ちなみに
この挙動を利用して、以下のように文字列にデフォルト値を設定することができる
a = s or 'foo' # sがFalseなら'foo'を代入
挙動としては以下と同じです。
a = s if s else 'foo'