Python | データ構造強化:set の積集合

Python Python
スポンサーリンク
  1. 概要(set の積集合は「共通して含まれる要素だけ」を取り出す基本操作)
  2. 基本の使い方(ここが重要)
    1. 演算子「&」とメソッド intersection の違いと使い分け
    2. リストやタプルは「set へ変換」してから積集合を取る
    3. 破壊的更新が欲しいなら intersection_update
  3. 重要ポイントの深掘り(性能・型・境界条件)
    1. 大量データでは「小さい集合から順に」積集合すると速い
    2. 値はハッシュ可能(不変)である必要がある
    3. 空集合や一方が空なら結果は空、1集合なら「その集合」
  4. 実務での使いどころ(権限・ファイル拡張子・検索条件の合致)
    1. ユーザー権限の共通チェック(ロールと必要権限)
    2. ディレクトリ間の共通ファイル名(拡張子やベース名で一致)
    3. AND 条件の検索(複数フィルタに同時合致)
  5. よくある落とし穴の回避(文字列の扱い・空集合の作り方・辞書との連携)
    1. 文字列は「文字集合」になる。単語集合にしたいなら split か set([…])
    2. 空集合は set() で作る。{} は空辞書
    3. 辞書のキー・値の積集合は「view」を使う
  6. 例題で身につける(定番から一歩先まで)
    1. 例題1:CSV の2列から共通商品名を抽出
    2. 例題2:2つの拡張子集合の共通(画像と添付の交差)
    3. 例題3:3集合の積集合をサイズ昇順で効率実行
    4. 例題4:条件合致ユーザーの集合を順に絞り込み
  7. まとめ

概要(set の積集合は「共通して含まれる要素だけ」を取り出す基本操作)

積集合(intersection)は、複数の集合に共通して含まれる要素だけを取り出します。重複は自動的に排除され、順序はありません。Python では演算子「&」かメソッド set.intersection(…) を使います。まずは「集合に変換 → 積集合 → 必要なら並べ替えや型へ戻す」という流れを身につけましょう。

A = {"apple", "banana", "orange"}
B = {"banana", "grape", "orange"}
print(A & B)                          # {'banana', 'orange'}
print(A.intersection(B))              # 同じ結果
Python

基本の使い方(ここが重要)

演算子「&」とメソッド intersection の違いと使い分け

「&」は2集合の積集合を簡潔に書けます。3つ以上の集合をまとめて扱うなら intersection の可変引数が読みやすいです。

A = {1, 2, 3, 4}
B = {3, 4, 5}
C = {4, 6}
print(A & B)                          # {3, 4}
print(A.intersection(B, C))           # {4}(3集合の共通)
Python

リストやタプルは「set へ変換」してから積集合を取る

集合演算は set 同士で行うのが基本線です。元がリストなら set(…) にしてから積集合、必要ならリストへ戻します。

tags1 = ["coffee", "tea", "sugar", "tea"]
tags2 = ["tea", "milk", "coffee"]
common = set(tags1) & set(tags2)
print(sorted(common))                 # ['coffee', 'tea']
Python

破壊的更新が欲しいなら intersection_update

「共通要素だけを残す」更新を1ステップで行えます。元集合を直接書き換えるので、コピーが不要な場面で有効です。

A = {"a", "b", "c"}
A.intersection_update({"b", "c", "d"})
print(A)                              # {'b', 'c'}
Python

重要ポイントの深掘り(性能・型・境界条件)

大量データでは「小さい集合から順に」積集合すると速い

積集合は「片方を順に走査し、他方の membership を調べる」処理です。最初に小さい集合で削ると後続が軽くなります。n 個の集合なら、サイズ昇順で reduce するのが定石です。

sets = [set(range(0, 100000, 2)), set(range(0, 100000, 3)), set(range(0, 100000, 5))]
sets.sort(key=len)
res = sets[0].intersection(*sets[1:])
Python

値はハッシュ可能(不変)である必要がある

set の要素はハッシュ可能(不変)である必要があります。リストは入れられませんが、タプルや frozenset はOKです。積集合の軸にするキー型を意識しましょう。

A = {("x", 1), ("y", 2)}
B = {("y", 2), ("z", 3)}
print(A & B)                          # {('y', 2)}
Python

空集合や一方が空なら結果は空、1集合なら「その集合」

積集合は「共通部分」なので、空集合が混じれば空になります。境界挙動を前提にして分岐を書きすぎないのがコツです。

print({1,2}.intersection(set()))      # set()
print({1,2}.intersection({1,2}))      # {1,2}
Python

実務での使いどころ(権限・ファイル拡張子・検索条件の合致)

ユーザー権限の共通チェック(ロールと必要権限)

「必要権限のうち、ユーザーのロールが持つものがあるか」を積集合で瞬時に判定できます。

user_perms    = {"read", "export"}
required_any  = {"write", "export"}
ok = bool(user_perms & required_any)   # 共通が1つでもあれば True
Python

ディレクトリ間の共通ファイル名(拡張子やベース名で一致)

複数フォルダに重複して存在するファイルを見つけたいとき、集合+積集合で簡潔に書けます。

from pathlib import Path

def names(root): return {p.name for p in Path(root).iterdir() if p.is_file()}
common = names("dirA") & names("dirB")
print(sorted(common))
Python

AND 条件の検索(複数フィルタに同時合致)

各条件で「合致したIDの集合」を作り、最後に積集合します。個々のフィルタを独立にテストでき、結合が明確になります。

cheap   = {101, 102, 105}
popular = {102, 104, 105}
in_stock= {102, 105, 106}
result  = cheap & popular & in_stock   # {102, 105}
Python

よくある落とし穴の回避(文字列の扱い・空集合の作り方・辞書との連携)

文字列は「文字集合」になる。単語集合にしたいなら split か set([…])

“ABC” を set にすると {‘A’,’B’,’C’} になります。単語の共通を取りたいときはトークン化しましょう。

s1 = "coffee tea sugar"
s2 = "tea milk coffee"
print(set(s1.split()) & set(s2.split()))   # {'tea', 'coffee'}
Python

空集合は set() で作る。{} は空辞書

空集合が欲しいのに {} と書くと dict になります。積集合の初期値で間違えやすいポイントです。

empty = set()
Python

辞書のキー・値の積集合は「view」を使う

辞書の共通キーや共通値を取りたいなら .keys() / .values() を集合演算にかけます。キーはハッシュ可能なので自然に扱えます。

A = {"id":1, "name":"hanako", "age":30}
B = {"id":1, "name":"taro",   "city":"Tokyo"}
print(A.keys() & B.keys())               # {'id', 'name'}
Python

例題で身につける(定番から一歩先まで)

例題1:CSV の2列から共通商品名を抽出

import csv

def common_items(path, colA, colB):
    with open(path, "r", encoding="utf-8", newline="") as f:
        rows = list(csv.reader(f))
    A = {r[colA] for r in rows if len(r) > colA}
    B = {r[colB] for r in rows if len(r) > colB}
    return A & B

# print(common_items("sales.csv", 0, 1))
Python

例題2:2つの拡張子集合の共通(画像と添付の交差)

images = {".png", ".jpg", ".gif"}
attachments = {".pdf", ".jpg", ".zip"}
print(images & attachments)              # {'.jpg'}
Python

例題3:3集合の積集合をサイズ昇順で効率実行

sets = [{1,2,3,4,5}, {3,4,5,6}, {4,5}]
sets.sort(key=len)
res = sets[0].intersection(*sets[1:])
print(res)                               # {4, 5}
Python

例題4:条件合致ユーザーの集合を順に絞り込み

active   = {1,2,3,4,5}
paid     = {2,3,5,7}
japan    = {1,3,5,8}
target   = active & paid & japan         # {3,5}
Python

まとめ

set の積集合は「複数集合の共通部分」だけを取り出す最短手段です。演算子「&」は2集合に簡潔、複数なら intersection を使う。リストはまず set に変換し、破壊的更新が必要なら intersection_update。大量データは小さい集合から順に絞ると速い。文字列は文字集合になる点、空集合は set() で作る点、辞書は keys()/values() 経由で扱う点に注意。積集合を「AND 条件の基本」として習慣化すれば、権限判定、重複検出、検索の絞り込みまで、短く正確に書けます。

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