LoginSignup
2
1

More than 3 years have passed since last update.

【Python】【基本】or演算子の振る舞い【(a in c) or (b in c)と(a or b) in c)の違い】

Posted at

概要

nltkの学習中に以下のようなコードが。

>>> sorted(t for t in set(text2) if "cie" in t or 'cei' in t)

ここでのtext2はnltkに最初から備え付けてあるTextオブジェクトなのですが、中身としては"Sense and Sensibility"という小説になっています。日本語だと「分別と多感」という名前で知られているようですね(未読)。

アホな私は、

>>> sorted(t for t in set(text2) if ("cie" or "cei") in t)

と同じじゃない?と思って試してみると、チュートリアル側のコードでは"ceiling"が要素に含まれているのに、自作のコードでは含まれていないという状態に。実際にその部分だけ判定を抜き出して見ると、以下のようになります。

print("cie" in "ceiling" or "cei" in "ceiling")
print(("cie" or "cei") in "ceiling")
出力結果
True
False

なんでこんなことに?

or演算子の挙動をしっかりと理解していなかったが故の末路です。こちらの記事を参考にさせていただくと、"cie" or "cei"は、以下のコードと等価です。

if bool("cie"):
    return "cie"
else:
    return "cei"

Pythonは1文字以上の文字列はTrueだと評価するので、if bool("cie"):は常にTrueになり、結果として"cie"しか返ってきません。そりゃ"ceiling"なんて入ってこないわけだ。

チュートリアル側のコードであれば、

if bool("cie" in "ceiling"):
    return "cie" in "ceiling"
else:
    return "cei" in "ceiling"

となり、if側でFalseとなりますが、elseでは"cei" in "ceiling"、すなわちTrueが返ってきます。結果として「文字列に"cei"か"cie"があれば」という判定をしっかりとこなせるわけですね。

オマケ

なお、勉強ついでにandの場合の挙動も確認しておくと、

if not bool("cie"):
    return "cie"
else:
    return "cei"

と等価になります。bool("cie")は常にTrueなので、この場合はelse文に入って必ず"cei"が入ってくることになりますね。

まとめ

前も似たようなことで引っかかった記憶があるのですが、その時は「何故か動く」の精神でスルーしていました。しっかりと調べて覚えて、記録しておくのは大事ですねホント。今後も頑張ります。

集合知に感謝。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1