概要(in / not in は「含まれるか」を判定する所属検査演算子)
in / not in は、ある値がリスト・タプル・文字列・セット・辞書などの「中に含まれているか」を真偽値で返す演算子です。in は含まれていれば True、not in は含まれていなければ True(in の否定)になります。文字列では「部分文字列として含まれるか」を判定できるのが直感的で便利です。
fruits = ["apple", "banana", "orange"]
print("apple" in fruits) # True
print("grape" not in fruits) # True
text = "Hello, world!"
print("Hello" in text) # True(部分一致)
print("hello" in text) # False(大小は区別)
Python基本構文と評価の流れ(ここが重要)
構文と返り値
「要素 in(または not in)コレクション」で書きます。結果は True/False の真偽値です。not in は in の結果を否定する形で評価され、書式はそのまま「要素 not in コレクション」で構いません。
nums = [1, 2, 3, 4, 5]
print(3 in nums) # True
print(6 not in nums) # True
Pythonif 条件での自然な使い方
in / not in は比較演算子なので、if の条件にそのまま置けます。読みやすく、明確です。
users = {"hanako", "taro"}
name = "hanako"
if name in users:
print("ログイン可")
else:
print("未登録")
Pythonデータ型ごとの挙動(文字列・リスト/タプル・セット・辞書)
文字列:部分一致判定(大小は区別)
文字列に対する in は「部分文字列として含まれるか」を調べます。大小(大文字/小文字)は区別されます。
text = "Hello, world!"
print("o," in text) # True
print("hello" in text) # False(case-sensitive)
Pythonリスト/タプル:等価比較によるメンバーシップ
シーケンスに対する in は、左から順に等価比較して一致が見つかれば True を返します。要素型が混在する場合は、比較ルールに注意しましょう。
nums = [10, 20, 30]
print(20 in nums) # True
print(99 in nums) # False
Pythonセット:高速な存在確認(ハッシュによる探索)
セットの in はハッシュを用いた高速検索が特徴です。大量要素の存在確認に向いています。
ids = set(range(100000))
print(12345 in ids) # 高速に True
Python辞書:対象は「キー」だけ(値は対象外)
dict に対する in は「キーの存在」を調べます。値の存在確認は d.values() を使う必要がありますが、値検索は線形走査になります。
user = {"name": "Hanako", "age": 20}
print("name" in user) # True(キー)
print(20 in user) # False(キーではない)
print(20 in user.values()) # True(値の中)
Python性能と設計の勘所(重要ポイントを深掘り)
設計方針:高速化が必要ならセット/辞書を選ぶ
- セット/辞書の in はハッシュ参照で高速。大量データの存在確認は、まずデータ構造をセット/辞書に寄せると効果的です。リスト/文字列は先頭からの線形探索なので、大きいほど遅くなります。
文字列判定は明確な仕様に
- 文字列の in は部分一致・大小区別。要件次第で前処理(lower/casefold)や完全一致(==)へ切り替えると誤判定を防げます。
辞書は「キー」判定が基本
- dict への in はキーのみ対象。値判定が必要なら values()/items() と組み合わせるのが安全です。
よくある落とし穴と安全策
文字列 in の意図しない部分一致
「’pro’ in ‘profile’」は True。完全一致が要件なら == を使うか、単語境界の正規表現で明示します。
print("pro" in "profile") # True(部分一致)
print("pro" == "profile") # False(完全一致)
Python辞書の in を値判定に誤用
dict で「値の存在」を in で調べると誤り。キー判定と値判定を使い分けます。
d = {"A": 1, "B": 2}
print(1 in d) # False(キーではない)
print(1 in d.values()) # True(値の中)
Python大文字小文字の違いで見逃し
文字列判定は大小区別。事前に統一(lower/casefold)すると堅牢になります。
text = "Hello"
print("hello" in text.lower()) # True(前処理で統一)
Python例題(定番から一歩先まで)
例題1:ブラックリスト判定(セットで高速化)
blacklist = {"spam@example.com", "bot@x"}
email = "spam@example.com"
if email in blacklist:
print("拒否") # 高速な存在確認
Python例題2:辞書の必須キー検証
required = {"name", "age", "email"}
payload = {"name": "Taro", "age": 25}
missing = required - payload.keys()
if missing:
print("不足:", ", ".join(sorted(missing)))
Python例題3:文字列の部分一致(ケース統一)
query = "tea"
text = "Tea Latte"
if query.lower() in text.lower():
print("ヒット")
Python例題4:値でフィルタ(items と組み合わせ)
prices = {"coffee": 350, "tea": 280, "juice": 220}
expensive = {k: v for k, v in prices.items() if v >= 300}
print(expensive) # {'coffee': 350}
Pythonまとめ
in / not in は「含まれるか」を簡潔に判定する所属検査演算子です。文字列では部分一致、辞書ではキー判定、セット/辞書は高速、リスト/文字列は線形探索と挙動の違いを押さえると迷いません。要件に応じて前処理(casefold/lower)やデータ構造の選択(セット/辞書化)を行い、辞書の値判定は values()/items() を併用するのが安全な作法です。
