【初心者必見】Pythonのsetで要素を検索・判定する方法まとめ

python

Pythonのset(集合)は、リストとは違って順番がなく、同じものが重複しないデータの入れ物です。

そして、setの大きな利点のひとつが「とても速い検索」です。

例えば、ある要素が存在するかどうかを調べるとき、リストに比べてsetは数倍速く処理できます。

この記事では、そんなsetを使った検索・存在確認・条件に合うデータの抽出方法を、わかりやすい例とともに説明します。

スポンサーリンク

setに特定の要素があるかどうか調べる

in演算子で簡単チェック

colors = {"red", "blue", "green"}
print("red" in colors)     # 結果: True
print("yellow" in colors)  # 結果: False

説明:

  • inを使うと、要素があるかどうかを簡単に調べられます
  • 存在する → True
  • 存在しない → False

実用例:

favorite_colors = {"red", "blue", "green"}
user_choice = "red"

if user_choice in favorite_colors:
    print(f"{user_choice}は好きな色です!")
else:
    print(f"{user_choice}は好きな色ではありません")

not inで否定の条件も可能

colors = {"red", "blue", "green"}
if "black" not in colors:
    print("blackは含まれていません")

説明:

  • not inを使うと、「含まれていない」という条件を簡単に書けます

実用例:

banned_words = {"暴力", "差別", "詐欺"}
user_message = "こんにちは"

if user_message not in banned_words:
    print("メッセージを投稿しました")
else:
    print("不適切な内容が含まれています")

まとめ

  • in / not in最も簡単で高速な検索方法
  • 使い方が直感的で理解しやすい

複数の要素が含まれているかを調べる

任意のひとつでも一致するか?(積集合を使用)

warning_keywords = {"error", "fail", "timeout"}
log_message = {"start", "connect", "timeout"}

# 共通する要素があるかチェック
common_words = warning_keywords & log_message
if common_words:
    print(f"警告ワードが見つかりました: {common_words}")

説明:

  • &は**共通要素(積集合)**を求める演算子です
  • 結果が空でなければ、一致する要素があることを意味します

より分かりやすい書き方:

warning_keywords = {"error", "fail", "timeout"}
log_words = ["start", "connect", "timeout", "end"]

# ログの中に警告ワードがあるかチェック
has_warning = any(word in warning_keywords for word in log_words)
if has_warning:
    print("警告ワードが含まれています")

すべて含まれるか?(issubset)

required_items = {"apple", "banana"}
shopping_basket = {"apple", "banana", "orange", "grape"}

# 必要なものがすべて揃っているかチェック
print(required_items.issubset(shopping_basket))  # 結果: True

説明:

  • issubset()は、「すべての要素が含まれているか」を調べます
  • 必要な条件がすべて満たされているかをチェックするときに便利です

実用例:

required_skills = {"Python", "SQL"}
candidate_skills = {"Python", "SQL", "JavaScript", "HTML"}

if required_skills.issubset(candidate_skills):
    print("応募条件を満たしています")
else:
    missing = required_skills - candidate_skills
    print(f"不足スキル: {missing}")

まとめ

  • 「ひとつでも一致」→ &演算子やany()
  • 「全部含まれる」→ issubset()

set検索を使ったループ・抽出処理

条件に一致する要素だけを取り出す

available_fruits = {"apple", "banana", "lemon", "peach"}
citrus_fruits = {"lemon", "orange", "lime"}

# 利用可能な柑橘類を見つける
available_citrus = available_fruits & citrus_fruits
print(available_citrus)  # 結果: {'lemon'}

説明:

  • 2つのセットから共通する要素だけを抽出できます
  • 在庫チェックや条件マッチングに便利です

リスト内包表記+set検索でフィルタ処理

all_words = ["apple", "car", "banana", "train", "orange"]
prohibited_words = {"car", "train"}

# 禁止ワード以外の言葉だけを抽出
allowed_words = [word for word in all_words if word not in prohibited_words]
print(allowed_words)  # 結果: ['apple', 'banana', 'orange']

説明:

  • リスト内包表記とnot inを組み合わせると、条件に合わない要素を除外できます
  • フィルタリング処理でよく使われるパターンです

別の書き方:

# for文を使った場合
allowed_words = []
for word in all_words:
    if word not in prohibited_words:
        allowed_words.append(word)

for文とif文での検索例

user_inputs = ["hello", "spam", "world", "virus"]
dangerous_words = {"spam", "virus", "malware"}

for word in user_inputs:
    if word in dangerous_words:
        print(f"危険ワード発見: {word}")
    else:
        print(f"安全な入力: {word}")

実行結果:

安全な入力: hello
危険ワード発見: spam
安全な入力: world
危険ワード発見: virus

まとめ

  • 検索を使った条件抽出やフィルタ処理は、setとの相性が抜群
  • リスト内包表記と組み合わせると、コードが短くて読みやすくなります

set検索の速度比較

なぜsetが速いのか?

import time

# 大きなデータで速度比較
large_list = list(range(100000))
large_set = set(range(100000))

search_value = 99999

# リストでの検索
start_time = time.time()
result = search_value in large_list
list_time = time.time() - start_time

# セットでの検索
start_time = time.time()
result = search_value in large_set
set_time = time.time() - start_time

print(f"リスト検索時間: {list_time:.6f}秒")
print(f"セット検索時間: {set_time:.6f}秒")
print(f"セットはリストより約{list_time/set_time:.1f}倍速い")

理由:

  • リスト:最初から順番に確認するため、要素が多いと時間がかかる
  • セット:ハッシュという仕組みを使って、一瞬で見つけられる

set検索の注意点とリストとの違い

特徴setlist
検索速度とても速い要素が多いと遅い
順序順番は保たれない順番が保たれる
重複自動で取り除かれる重複OK
存在確認方法"値" in セット名"値" in リスト名

注意:setは順番がない

# 同じ要素でも表示順は毎回変わる可能性がある
my_set = set(["a", "b", "c"])
print(my_set)  # 結果例: {'c', 'a', 'b'}

対策: 順番が重要な場合は、リストと併用します

# 順番を保ちながら重複を取り除く
original_list = ["b", "a", "c", "a", "b"]
unique_items = []
seen = set()

for item in original_list:
    if item not in seen:
        unique_items.append(item)
        seen.add(item)

print(unique_items)  # 結果: ['b', 'a', 'c']

注意:変更可能な型は検索できない

# これはエラーになる
my_set = set()
my_set.add([1, 2])  # エラー: TypeError

理由: リストは内容を変更できるため、セットに入れることができません

対策: タプルに変換して使用します

my_set = set()
my_set.add((1, 2))  # タプルなら追加可能
print(my_set)  # 結果: {(1, 2)}

実践的な使用例

ユーザー権限のチェック

user_permissions = {"read", "write"}
required_permissions = {"read", "write", "delete"}

# 必要な権限がすべて揃っているかチェック
if required_permissions.issubset(user_permissions):
    print("操作を実行できます")
else:
    missing = required_permissions - user_permissions
    print(f"不足している権限: {missing}")

商品の在庫チェック

available_products = {"laptop", "mouse", "keyboard", "monitor"}
customer_order = {"laptop", "printer", "mouse"}

# 注文可能な商品と不可能な商品を分ける
available_items = customer_order & available_products
unavailable_items = customer_order - available_products

print(f"注文可能: {available_items}")
print(f"在庫なし: {unavailable_items}")

ログファイルの分析

error_keywords = {"error", "failed", "timeout", "exception"}
log_lines = [
    "user login successful",
    "database connection failed",
    "file uploaded successfully",
    "timeout occurred during operation"
]

error_lines = []
for i, line in enumerate(log_lines):
    words = set(line.lower().split())
    if error_keywords & words:  # 共通要素があるか
        error_lines.append(f"行{i+1}: {line}")

print("エラーを含む行:")
for error_line in error_lines:
    print(error_line)

まとめ

操作内容方法・関数使う場面
要素があるか調べる"a" in my_set基本的な存在確認
複数の一致を探すset1 & set2共通要素を見つけたい
全部含まれているかset1.issubset(set2)条件がすべて満たされているか
フィルタ処理if word not in ng_words不要なデータを除外
高速な検索処理set型を使用大量データの検索

コメント

タイトルとURLをコピーしました