3秒でわかる
同じ値を 2 つ以上持たず、順序も持たないデータ構造。含まれているかの判定が要素数によらず速く、重複除去や集合演算に向いています。
30秒図解
もう少し詳しく
どういうものか
セット (集合) は、同じ値を 2 つ以上持たないデータ構造です。要素に順番の概念が無く、番号で取り出すことはできません。その代わり、ある値が入っているかどうかの判定が非常に速く、要素が 10 件でも 100 万件でもほぼ同じ時間で終わります。内部でハッシュ表を使い、値そのものから格納位置を計算しているためです。Python の set、JavaScript の Set、Java の HashSet がこれにあたります。
なぜ必要か
リストに対して「この値が含まれるか」を調べると、先頭から順に比較するため、要素数に比例して遅くなります。1 万件のリストに対して 1 万回の判定を行うと 1 億回の比較になり、体感で分かるほど待たされます。同じ処理をセットで行うと一瞬で終わります。
重複の除去にも使えます。ログから利用者 ID の種類数を数えるような処理は、セットに入れて件数を取るだけで済みます。
具体例
ids = [3, 1, 3, 7, 1]
unique = set(ids) # {1, 3, 7}
print(len(unique)) # 3
print(7 in unique) # True
a = {1, 2, 3}
b = {2, 3, 4}
print(a & b) # {2, 3} 共通部分
print(a | b) # {1,2,3,4} 和
print(a - b) # {1} 差const s = new Set([3, 1, 3, 7]);
s.add(9);
console.log(s.has(7), s.size); // true 3+1
console.log([...s]); // <a href="/glossary/array" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">配列</a>へ戻す似た用語との違い
| 構造 | 重複 | 順序 | 主な用途 |
|---|---|---|---|
| 配列 / リスト | あり | あり | 並び順が意味を持つデータ |
| セット | なし | なし | 存在判定、重複除去、集合演算 |
| 辞書 / マップ | キーは重複なし | 実装による | キーに値を紐づける |
セットは、値だけを持つ辞書だと考えると理解しやすくなります。
つまずきやすいところ
順序が保証されないことを忘れると、表示順が実行のたびに変わるバグになります。画面に出す前には必ず並べ替えます。JavaScript の Set は挿入順を保つ仕様ですが、Python の set は保ちません。言語をまたぐと前提が変わります。
もうひとつは、変更できる値を入れられないことです。Python でリストを set に入れようとするとエラーになります。ハッシュ値が途中で変わると位置が狂うためで、タプルに変換してから入れます。
辞書やオブジェクトを重複除去したい場合も注意が要ります。JavaScript の Set は参照で同一性を判断するため、中身が同じオブジェクトでも別物として両方残ります。判定に使いたい項目を文字列にしてから入れる必要があります。