条件式 and,or
Pythonを書く時、論理演算子としてandやorを使って、条件式を書くことがある。(JavaScriptやCでは && や || で表現する)
有名なもので、FizzBuzz問題の3の倍数かつ5の倍数を表現するときにandが使われることが例に挙げられる。
複数文字列がinで囲まれた大きな文字列に含まれるかどうか
次のような場合を考える
if "abc" or "def" in "ghi":
print("True")
else:
print("False")
>>> True
直感的には、"abc"も"def"も"ghi"には含まれていないため、Falseが返ることが期待されますが、実際には、予想と反するTrueが返ってきます。
これがなぜかというと、pythonでは次のように解釈されているためです。
if "abc" or ("def" in "ghi"):
...
この場合、左側の条件式"abc"が真として扱われるため、右側の条件式が評価されることなく、if文はTrueとなります。
if文の改善を試みる
example1.pyの改善を試みます。
# パターン1
if ( "abc" or "def" ) in "ghiabc":
print("True")
else:
print("False")
>>> True
# パターン2
if ( "abc" or "def" ) in "ghidef":
print("True")
else:
print("False")
>>> False
パターン1は期待通りに結果が返ってきますが、パターン2では期待に反する結果が返ってきます。
このことから、パターン2のように書いた場合、左側の条件項(今回の場合"abc")のみが評価対象になっています。
そのため、評価対象のみを括弧で囲むことは、解決策にはなりません。
結論から言うと、example1.pyに書いたコードを期待通りに実行する場合は次のように書く必要があります。
if "abc" in "ghi" or "def" in "ghi":
print("True")
else:
print("False")
>>> False
example4.pyでは、各条件に対して評価を行っています。
これが確実なコーディング方法です。
まとめ
Pythonで複数文字列の演算子を使た条件式を書く場合、直感とは反する結果が返ってくることがある。
内部的にどう処理されているかを把握しておくことで、コーディング時に困惑することが少なくなるかと思います。