順番に読み進めながら学べます

集合型 (set) の使い方

Python の集合型 set を基礎から解説します。重複なし・順序なしの特徴、要素操作、集合演算、実用パターンまで一通り図解で押さえます。

set とは — 重複なし・順序なし

集合 (set) は、リストやタプルと同じく複数の値をまとめるための型ですが、2 つだけ大きく違うルールがあります。

- 同じ値は 1 つだけしか持てない(重複を自動で取り除く

- 順序を保持しない並びに意味がない

set の特徴 — 重複は消える、順序は固定されない
{a,b,c,d,a}set 化{a,b,c,d}(順不同)宣言結果

同じ値を入れても、重複は削除され 1 つしか残りません

(この例では a が 1 つになっています)

{ と } で囲んで、カンマ区切りで値を並べて宣言します。

空の集合を作りたいときは {} ではなく set() を使ってください。{} だと空の辞書になります。

# 重複は自動で消える
set_a = {"a", "b", "c", "d", "a"}
print(set_a)         # {'a', 'b', 'c', 'd'}(順番は環境によって変わる)
print(type(set_a))   # <class 'set'>
print(len(set_a))    # 4(重複した 'a' は 1 つにまとまる)

# 数値や混在型もOK
mixed = {1, "apple", 3.14}

# 空の集合は set() を使う
empty_set  = set()
empty_dict = {}        # こちらは「空の辞書」になる
print(type(empty_set))   # <class 'set'>
print(type(empty_dict))  # <class 'dict'>

# 含まれているかの確認は in / not in
print("a" in set_a)       # True
print("z" not in set_a)   # True

順序がないので、インデックスでは取り出せない

set は順序を持たないため、set_a[0] のようなインデックスアクセスはできませんTypeError になります)。「○番目の要素を取りたい」場合は、list か tuple に変換してから取り出してください。「並びに意味があるなら list / tuple、無いなら set」 と用途で選び分けましょう。

set の基本動作を確認しましょう。

tags = {"python", "web", "python", "ai", "web"} を作り、tags の中身と len(tags)print() で表示してください。重複が消えて要素数が減るはずです。

"python" in tags"go" in tags をそれぞれ print() で表示し、含まれているかを True / False で確認してください。

(正しく実行できれば解説が表示されます)

Python エディタ

コードを実行してください

要素の追加と削除

set はミュータブル(変更可能)な型なので、宣言したあとに要素を追加・削除できます。

よく使うメソッドは次の 5 つです。

メソッド役割ポイント
add(x)要素 x を追加既にあれば何もしない(重複は無視)
remove(x)要素 x を削除x が無ければ KeyError
discard(x)要素 x を削除x が無くてもエラーにならない
pop()任意の要素を 1 つ取り出して削除どれが取り出されるかは決まらない
clear()全要素を削除空の set になる
fruits = {"apple", "banana", "lemon"}

# 追加
fruits.add("grape")
fruits.add("apple")     # 既にあるので無視される
print(fruits)            # {'apple', 'banana', 'lemon', 'grape'}

# 削除(remove は無いとエラー)
fruits.remove("banana")
# fruits.remove("melon") # KeyError

# discard は無くてもエラーにならない
fruits.discard("melon")  # 何も起きない
print(fruits)            # {'apple', 'lemon', 'grape'}

# 任意の要素を取り出して削除
picked = fruits.pop()
print(picked)            # どれか 1 つ(実行ごとに変わる)

# 全部空にする
fruits.clear()
print(fruits)            # set()
remove と discard の使い分け
remove(x)x が無いKeyErrordiscard(x)x が無い何もしない削除エラー削除OK

「無いはずの値が紛れ込んでいたら気付きたい」 ときは remove(エラーで知らせる)。

「あれば消したいだけ、無くても気にしない」 ときは discard

ユーザーの興味タグを管理してみましょう。

interests = {"python", "web"} が用意されています。

add"ai" を追加してください。

既にある "python" をさらに add してみて、結果が変わらないことを確認してください。

discard"go"(存在しないタグ)を削除してみて、エラーが出ないことを確認してください。

④ 最終的な interestsprint() で表示してください。

Python エディタ

コードを実行してください

集合演算 — 和集合・積集合・差集合・対称差

set の最大の機能が集合演算です。2 つの集合を組み合わせて、共通する要素やどちらか片方にしかない要素を一度に取り出せます。リストでも for 文で書けば同じことはできますが、set ははるかに速く処理ができます

  • 和集合(union) — どちらか一方でも含まれている要素を全部
  • 積集合(intersection) — 両方に含まれている要素だけ
  • 差集合(difference) — s にあって t にない要素
  • 対称差(symmetric_difference) — どちらか片方にしかない要素

以下の図は、s = {a, b, c, d}、t = {c, d, e, f} のときの結果です。

4 つの集合演算
和集合s | t.union{a,b,c,d,e,f}積集合s & t.intersection{c, d}差集合s - t.difference{a, b}対称差s ^ t.symmetric_difference{a,b,e,f}

演算子(| & - ^)メソッド(union など) はどちらを使ってもよいです。

s = {"a", "b", "c", "d"}
t = {"c", "d", "e", "f"}

# 和集合
print(s | t)                  # {'a', 'b', 'c', 'd', 'e', 'f'}
print(s.union(t))             # 同じ

# 積集合
print(s & t)                  # {'c', 'd'}
print(s.intersection(t))      # 同じ

# 差集合(s に含まれて t に含まれないもの)
print(s - t)                  # {'a', 'b'}
print(s.difference(t))        # 同じ

# 対称差(どちらか片方にしか無いもの)
print(s ^ t)                  # {'a', 'b', 'e', 'f'}
print(s.symmetric_difference(t))  # 同じ

部分集合の判定(参考)

a <= b あるいは a.issubset(b) で、「a の要素がすべて b に含まれているか」を True / False で確認できます。逆方向は a >= ba.issuperset(b)

用途としては「ユーザーが持っている権限の集合に必須権限の集合がすべて含まれているか」のようなチェックに用います。初めのうちは「集合演算」を優先して覚え、必要になったタイミングで使いましょう。

2 つのクラスの履修者リストから「両方履修」と「片方だけ履修」の生徒を求めましょう。

math = {"Alice", "Bob", "Carol", "Dan"}english = {"Carol", "Dan", "Eve", "Frank"} が用意されています。

両方を履修している生徒(積集合)を print() で表示してください。

片方しか履修していない生徒(対称差)を print() で表示してください。

Python エディタ

コードを実行してください

実用パターン — 重複削除と高速な存在チェック

最後に、実務で本当によく使う 2 つの定番パターンを押さえておきましょう。

set を活用して list の重複を削除
[1,2,2,3,4,4,5]list(set(...))[1,2,3,4,5]変換結果

list(set(...)) で「いったん set に変換して重複を消し、再度 list に戻す」パターンの利用が多いです。

1 行で書けて速く、for 文で重複判定するより圧倒的に簡潔です。

# パターン①: 重複削除
numbers = [1, 2, 2, 2, 3, 4, 4, 5, 6, 6]
unique_numbers = list(set(numbers))
print(unique_numbers)   # [1, 2, 3, 4, 5, 6](順序は環境によって変わる)

# パターン②: 高速な存在チェック
# x in set は、x in list よりずっと速い
allowed_users = {"alice", "bob", "carol"}
print("alice" in allowed_users)   # True
print("dan"   in allowed_users)   # False

なぜ set の in は速いのか

set は内部でハッシュテーブルというデータ構造を使っています。これは「値を計算結果(ハッシュ)から直接探す」仕組みで、要素数が増えてもほぼ一定の時間で見つけられます。

リストの in先頭から順番に比較していくため、要素数が増えるほど遅くなります。「含まれているかを何度もチェックする」用途なら、最初に set に変換しておくと一気に速くなる、と覚えておくと役立ちます。

ログから重複を削除し、さらに指定ユーザーが存在するかを高速に確認してみましょう。

logins = ["alice", "bob", "alice", "carol", "bob", "alice"] が用意されています。

set を使って重複を削除した結果を unique_logins(list 型)として作り、print() で表示してください。

unique_loginsそのまま set に変換した login_set を作り、"carol""dan" がそれぞれ含まれるかを inprint() してください。

Python エディタ

コードを実行してください

この記事では、set の特徴(重複なし・順序なし)、追加と削除のメソッド集合演算、そして重複削除と高速な存在チェックという実用パターンを学びました。

「並びは要らない、ユニークなものだけが欲しい」「含まれているかを何度も確認したい」「集合の重なりを取りたい」 — このどれかに当てはまったら、set の出番です。

QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1次のうち正しく set を作れているのはどれですか?

Q2s = {1, 2, 3} に対して s.discard(99) を実行するとどうなりますか?(99 は含まれていません)

Q3s = {1, 2, 3, 4}t = {3, 4, 5, 6} のとき、s & t の結果はどれですか?