閉じる

Pythonのin演算子でリストに値が含まれるかを判定する方法

Pythonのin演算子は、リストに特定の要素が含まれるかをシンプルに判定できる強力な道具です。

for文で総当たりしなくても、1行で可読性と安全性を両立できます。

本記事では、基本構文からつまずきやすいポイント、ネストや辞書の応用、さらに高速化のコツまで段階的に丁寧に解説します。

in演算子でリストに値が含まれるか判定

構文(value in list)

基本構文

リストに要素が含まれるかどうかはvalue in some_listで判定します

結果はTrueまたはFalseのブール値です。

Python
# 基本構文の例
fruits = ["apple", "banana", "orange"]

# "banana" がリストにあるか確認
print("banana" in fruits)  # True

# "grape" がリストにあるか確認
print("grape" in fruits)   # False
実行結果
True
False

演算子inは「左辺の値が右辺のコンテナに含まれているか」を調べます

右辺はリストのほか、文字列、タプル、セット、辞書(キーを対象)などにも使えます。

戻り値(bool)と判定結果

ブール値として返る

戻り値はboolで、if文や三項演算子などでそのまま使用できます。

Python
numbers = [2, 4, 6, 8]
exists = 4 in numbers  # bool の True が入る
print(type(exists), exists)

# if での分岐
if 10 in numbers:
    print("10は含まれます")
else:
    print("10は含まれません")
実行結果
<class 'bool'> True
10は含まれません

典型パターン

存在チェックは副作用なく読みやすい条件式になります

早期リターンなどと組み合わせるとコードが明快になります。

否定形(not in)の使い方

含まれていないことを確認する

含まれていないことを確かめたい場合はnot inを使います。

Python
blocked_users = ["alice", "bob"]
user = "carol"

if user not in blocked_users:
    print(f"{user} はアクセス可能です")
else:
    print(f"{user} はブロックされています")
実行結果
carol はアクセス可能です

読みやすさのコツ

肯定形と否定形は読み手に与える印象が異なります

ポリシーに合わせて「許可リスト」または「拒否リスト」で管理すると条件が分かりやすくなります。

例(数値リスト/文字列リスト)

数値リストの例

Python
scores = [55, 70, 85, 90]

print(70 in scores)   # True
print(100 in scores)  # False
実行結果
True
False

文字列リストの例

Python
langs = ["Python", "JavaScript", "Go"]

print("Python" in langs)   # True
print("python" in langs)   # False (大文字小文字は区別される)
実行結果
True
False

初心者がつまずくポイント

部分一致ではない(文字列の誤解に注意)

リスト要素は「完全一致」で比較される

リストに対するinは部分一致ではありません

各要素と左辺の値を==で比較し、一致する要素があるかを調べます

Python
words = ["banana"]
print("na" in words)        # False: リスト要素とは部分一致しない
print("banana" in words)    # True: 完全一致はOK

# 文字列そのものに対する in は「部分文字列」検索になる点に注意
print("na" in "banana")     # True: こちらは文字列の部分一致
実行結果
False
True
True

よくある誤解

「リストの中の文字列に部分一致するか」を調べるには、要素ごとにチェックする必要があります

Python
words = ["apple", "banana", "orange"]
needle = "na"
print(any(needle in w for w in words))  # True ("banana" に "na" が含まれる)
実行結果
True

型の違い(1と’1’は別物)

文字列と数値は別型

1'1'は別物です。

型が異なると==は通常Falseになります。

Python
values = [1, 2, 3]
print("1" in values)  # False: 文字列 "1" は含まれない
print(1 in values)    # True
実行結果
False
True

メモ

ブール値は数値と等価比較されることがあるため(例: True == 1True)、混在リストでは思わぬ一致が起きます。

型をそろえるか、データ設計でブールと数値を混在させないのが安全です。

大文字小文字の違い(case sensitive)

大文字小文字は区別される

Python
names = ["Alice", "Bob"]
print("alice" in names)             # False
print("Alice".lower() in [n.lower() for n in names])  # True: 正規化して比較
実行結果
False
True

正規化の実践

比較前に小文字化(または大文字化)しておくことで入力ゆらぎを吸収できます。

空リストとNoneの判定

空リストに対する in

空リスト[]に対するinは常にFalseです。

Python
empty = []
print(1 in empty)  # False
実行結果
False

Noneと空リストは別物

Noneと空リストは異なるため、判定は目的に応じて分けます。

Python
data = None

# None かどうかは is で判定
if data is None:
    print("データがありません(None)")

# 空リストかどうかは長さや真偽値で判定
data = []
if not data:  # len(data) == 0 と同義
    print("空リストです")
実行結果
データがありません(None)
空リストです

ネストや複合データでの存在確認

ネストしたリストの探索(anyの併用)

any を使った内側探索

2次元リストに値が含まれるかは、各サブリストに対してinを適用しanyでまとめます

Python
grid = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
]

target = 4
found = any(target in row for row in grid)
print(found)  # True
実行結果
True

位置も知りたい場合

Python
# 見つかった最初の位置(行, 列)を返す
def find_position(grid, value):
    for r, row in enumerate(grid):
        if value in row:
            c = row.index(value)  # ここは発見済みなので安全に index を使える
            return r, c
    return None

print(find_position(grid, 7))  # (2, 1)
実行結果
(2, 1)

リスト内の辞書でキー/値を探すコツ

値で探す

Python
users = [
    {"id": 1, "name": "Alice"},
    {"id": 2, "name": "Bob"},
    {"id": 3, "name": "Carol"},
]

# id が 2 のユーザーが存在するか
exists = any(u.get("id") == 2 for u in users)
print(exists)  # True

# name が "Bob" の辞書だけ抽出
matched = [u for u in users if u.get("name") == "Bob"]
print(matched)
実行結果
True
[{'id': 2, 'name': 'Bob'}]

キーの存在で探す

辞書自体へのinキーの存在を調べます。

リスト内の各辞書に同じキーがあるかを検査する例です。

Python
# すべての要素が "name" キーを持つか
all_have_name = all("name" in u for u in users)
print(all_have_name)  # True
実行結果
True

効率化と関連テクニック

リストのinはO(n)とパフォーマンス

計算量の目安

リストのinは最悪で先頭から末尾まで走査するためO(n)です。

データが増えるほど比例して遅くなります。

以下はデータ構造ごとのおおよその計算量の比較です。

データ構造メンバーシップ平均計算量備考
リスト(list)O(n)先頭から順に比較
セット(set)O(1)ハッシュによる高速探索
辞書(dict)O(1)キー検索が高速
文字列(str)O(n)部分文字列検索

実務上の指針

大きなデータで頻繁に判定する場合、セット化を検討してください。

頻繁な判定はset化で高速化

set による高速 membership

Python
# リストからセットを1度だけ作って使い回すのがコツ
ids_list = list(range(100_000))
ids_set = set(ids_list)  # 構築は O(n)、以降の検索は平均 O(1)

print(42 in ids_list)  # O(n)
print(42 in ids_set)   # O(1) 相当で高速
実行結果
True
True

注意: セットは順序を保持しません。

また、リスト内の要素がリストなどの非ハッシュ可能型だとセットにできません。

if文での存在チェック

基本パターン

Python
emails = ["a@example.com", "b@example.com"]

address = "c@example.com"
if address in emails:
    print("登録済みです")
else:
    print("未登録のアドレスです")
実行結果
未登録のアドレスです

否定形と組み合わせる

否定条件ではnot inを用いると読みやすいです。

複数候補の判定(any・set)

any で少なくとも1つ一致

Python
candidates = [".jpg", ".png", ".gif"]
filename = "photo.png"

if any(filename.endswith(ext) for ext in candidates):
    print("画像ファイルです")
実行結果
画像ファイルです

set の積集合で高速判定

Python
required = {"read", "write"}
user_perms = ["read", "execute", "write"]

# 少なくとも1つ一致するか
print(bool(set(required) & set(user_perms)))  # True

# すべて含むか(包含判定)
print(set(required).issubset(user_perms))     # True
実行結果
True
True

フィルタリング(list内包表記とin)

許可リスト/禁止リストで絞り込み

Python
allowed = {"red", "green"}
colors = ["red", "blue", "green", "green", "yellow"]

# 許可された色だけ残す
filtered = [c for c in colors if c in allowed]
print(filtered)  # ["red", "green", "green"]

# 禁止リストで除外する
blocked = {"blue", "yellow"}
cleaned = [c for c in colors if c not in blocked]
print(cleaned)  # ["red", "green", "green"]
実行結果
['red', 'green', 'green']
['red', 'green', 'green']

index()との違いと使い分け

役割の違い

  • in: 含まれるかどうか(真偽)を返す。見つからなくても例外は出ない。
  • list.index(x): 最初に見つかった位置(インデックス)を返す。xがないとValueError

実例

Python
items = ["a", "b", "c"]

# 位置が欲しい場合は index を使うが、例外に注意
if "b" in items:               # 先に in で安全確認
    pos = items.index("b")     # ここは例外が出ない
    print(pos)                 # 1

# 直接 index を使うなら try/except で囲む
try:
    print(items.index("z"))
except ValueError:
    print("'z' は見つかりませんでした")
実行結果
1
'z' は見つかりませんでした

使い分けの目安

存在可否だけならin、位置が必要ならindex()

存在が不確実ならinで先に確認するか、try/exceptで握りましょう。

まとめ

リストに特定要素が含まれるかはinで簡潔かつ安全に判定できます

部分一致の誤解や型・大小文字の違い、空リストとNoneの区別など、つまずきポイントを押さえるだけでバグを大きく減らせます。

ネストや辞書ではanyや内包表記を活用し、頻繁な判定はset化で高速化しましょう。

用途に応じてinindex()を使い分ければ、読みやすく効率的なPythonコードを書けます。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!