10.

Python set (集合) 型完全ガイド(リテラル・和差積・frozenset・内包表記)

編集
この記事の要点
  • Python の set重複を許さない順序なしコレクション。要素の存在判定 inO(1)
  • リテラル {1, 2, 3}、空セットは set() ({} は辞書になる)
  • 集合演算: |&-対称差 ^
  • 主要メソッド: add / remove / discard / pop / update / issubset / issuperset
  • 不変版は frozenset辞書のキーや set の要素として使える

set とは

Python の set は数学の「集合」に相当するデータ型で、次の特徴を持ちます。

  • 重複なし: 同じ値は 1 つしか保持しない
  • 順序なし: 要素の並び順を保証しない (Python 3.7+ でも保証しない)
  • ハッシュ可能な要素のみ: int / str / tuple は OK、list / dict は NG
  • in 演算が O(1) 平均: list の O(N) に対して圧倒的に速い

作成方法

# リテラル
s1 = {1, 2, 3}
s2 = {'apple', 'banana'}

# set() コンストラクタ
s3 = set([1, 2, 3])         # list から
s4 = set('hello')           # 文字列から → {'h', 'e', 'l', 'o'} (l は重複削除)
s5 = set(range(5))          # range から → {0, 1, 2, 3, 4}

# 空セット
empty = set()               # ✅
wrong = {}                  # ❌ これは空の dict

# 集合内包表記
squares = {x ** 2 for x in range(10)}   # {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}

# 重複は自動的に除外される
nums = {1, 2, 2, 3, 3, 3}   # → {1, 2, 3}

集合演算 (union / intersection / difference / symmetric_difference)

演算演算子メソッド意味
和集合A | BA.union(B)どちらかに含まれる
積集合A & BA.intersection(B)両方に含まれる
差集合A - BA.difference(B)A にあって B にない
対称差A ^ BA.symmetric_difference(B)どちらか片方にだけ
部分集合A <= BA.issubset(B)A が B の部分集合か
真部分集合A < BA ⊂ B かつ A ≠ B
上位集合A >= BA.issuperset(B)A が B を含むか
互いに素A.isdisjoint(B)共通要素なし
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}

A | B   # {1, 2, 3, 4, 5, 6}
A & B   # {3, 4}
A - B   # {1, 2}
B - A   # {5, 6}
A ^ B   # {1, 2, 5, 6}

A <= {1, 2, 3, 4, 5}   # True (A は部分集合)
A.isdisjoint({10, 20}) # True

更新メソッド

s = {1, 2, 3}

s.add(4)            # → {1, 2, 3, 4}
s.add(2)            # 重複は無視 (エラーにならない)

s.remove(3)         # → {1, 2, 4}    存在しない要素だと KeyError
s.discard(99)       # 存在しなくてもエラーにならない (推奨)

popped = s.pop()    # 任意の 1 要素を取り出して削除 (順序不定)

s.clear()           # 空にする

# 破壊的集合演算
s = {1, 2, 3}
s |= {3, 4, 5}      # update      → {1, 2, 3, 4, 5}
s &= {2, 4, 6}      # intersection_update → {2, 4}
s -= {2}            # difference_update   → {4}
s ^= {4, 7}         # symmetric_difference_update → {7}

典型ユースケース 1: 重複削除

# list の重複削除 (順序不問)
nums = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(nums))   # [1, 2, 3, 4] (順序は保証されない)

# 順序を保ちつつ重複削除 (Python 3.7+ dict)
unique_ordered = list(dict.fromkeys(nums))   # [1, 2, 3, 4]

典型ユースケース 2: 高速な存在判定 (O(1))

# ❌ list の in は O(N)
allowed_ids = [1, 2, 3, ..., 1_000_000]
if user_id in allowed_ids:   # 最悪 100 万回比較
    ...

# ✅ set の in は O(1)
allowed_ids = {1, 2, 3, ..., 1_000_000}
if user_id in allowed_ids:   # ハッシュ参照 1 回
    ...

# 2 つのリストの共通要素を取得
common = set(list_a) & set(list_b)

典型ユースケース 3: 集合演算でフィルタ

# DB から取得した既存ユーザ ID と、リクエストで来た新規 ID
existing = {1, 2, 3, 4, 5}
incoming = {3, 4, 5, 6, 7}

to_insert = incoming - existing   # {6, 7}    INSERT すべきもの
to_delete = existing - incoming   # {1, 2}    DELETE すべきもの
to_update = incoming & existing   # {3, 4, 5} UPDATE すべきもの

frozenset (不変な集合)

set はハッシュ不可なので辞書のキーや set の要素にできません。frozenset は不変なのでハッシュ可能、辞書のキーや set の要素として使えます。

fs = frozenset([1, 2, 3])
fs.add(4)   # ❌ AttributeError: 'frozenset' object has no attribute 'add'

# 集合演算は通常の set と同じ
fs | {4, 5}    # frozenset({1, 2, 3, 4, 5})

# 辞書のキーに使える
groups = {
    frozenset({1, 2}): 'group A',
    frozenset({3, 4}): 'group B',
}

# set の要素として使える (set of sets)
set_of_sets = {frozenset({1, 2}), frozenset({3, 4})}

set に入れられない型

# ハッシュ可能でない型は要素にできない
s = {[1, 2]}      # ❌ TypeError: unhashable type: 'list'
s = {{1: 2}}      # ❌ TypeError: unhashable type: 'dict'
s = {{1, 2}}      # ❌ TypeError: unhashable type: 'set'

# tuple は OK (不変なのでハッシュ可)
s = {(1, 2), (3, 4)}   # ✅

計算量まとめ

操作setlist
x in sO(1)O(N)
s.add(x) / s.remove(x)O(1)O(N)
反復 (for)O(N)O(N)
和差積O(N+M)
順序保持×
index アクセス×O(1)

FAQ

Q: 順序を保ちたい set はある?
A: 標準にはありません。dict.fromkeys(seq) で代用するか、collections.OrderedDictsortedcontainers.SortedSet (サードパーティ) を使います。

Q: set のソート出力は?
A: sorted(s) で list を返します。set 自体はソートできません。

Q: 巨大データで set のメモリ使用量が気になる
A: set は dict と同じく要素 1 つあたり数十バイトのオーバーヘッド。1000 万件超なら array / NumPy / Bloom filter 等の検討を。

編集
Post Share
子ページ
  1. セットの作成
  2. 要素の追加
  3. 要素の削除
同階層のページ
  1. 基本的なルール
  2. 変数
  3. 演算子
  4. 標準ライブラリ
  5. 外部ライブラリ
  6. 制御構文
  7. リスト(配列)
  8. タプル
  9. セット
  10. 辞書(dict)
  11. クラスとメソッド
  12. 継承の概念と必要性
  13. 継承の構文
  14. コンストラクタ
  15. cookieの値の設定と取得
  16. 例外処理
  17. 例外を文字列で出力する方法
  18. httpリクエスト(curl)をする方法
  19. Responseオブジェクトの中身の確認
  20. 変数が空かどうか判定する方法
  21. タイムゾーンの設定と現在日時の取得と文字列化
  22. シングルクォーテーションとダブルクォーテーションの違い

最近更新/作成されたページ