【Python】セット(set)の基本と集合演算の使い方

Python

こんにちは、かつコーチです。

これまでリスト・タプル・辞書を解説してきましたが、今回はセット(set)を取り上げます。

セットとは、重複した値を持たない、順序のないデータ構造のことです。

「リストから重複を取り除きたいだけなのに、自分でループを書いて頑張っていた」というのが、私がセットの便利さに気づく前の状態でした。

この記事では、セットの作成方法(重複排除)と、和集合・積集合・差集合といった集合演算の使い方を解説します。

基本の書き方:セットの作成と重複排除

セットを作成する

セットは{}(波かっこ)、またはset()関数で作成します。

fruits = {"りんご", "みかん", "ぶどう"}
print(fruits)
# {'ぶどう', 'みかん', 'りんご'}

出力順序が入力順と異なる点に注意してください。

セットには「順序」という概念がないため、表示順は保証されません。

空のセットを作るときは、{}ではなくset()を使う必要があります。

empty_dict = {}
print(type(empty_dict))
# <class 'dict'>

empty_set = set()
print(type(empty_set))
# <class 'set'>

{}は辞書の空リテラルとして扱われるため、セットのつもりで書くと型を間違えてしまいます。

重複を排除する

セットの大きな用途の1つが、リストから重複を取り除くことです。

numbers = [1, 2, 2, 3, 3, 3, 4]
unique_numbers = set(numbers)
print(unique_numbers)
# {1, 2, 3, 4}

リストに戻したい場合は、list()で変換します。

unique_list = list(unique_numbers)
print(unique_list)
# [1, 2, 3, 4]

要素の追加・削除

要素の追加はadd()、削除はremove()またはdiscard()を使います。

fruits.add("メロン")
fruits.remove("みかん")
print(fruits)
# {'ぶどう', 'りんご', 'メロン'}

つまずきやすい設定・注意点

セットに追加できるのは、リストや辞書のように変更可能な値ではなく、タプルなどのイミュータブルな値に限られます。

group = {(1, 2), (3, 4)}

これはOKですが、リストをセットに入れようとするとエラーになります。

group = {[1, 2], [3, 4]}
TypeError: unhashable type: 'list'

よくあるつまずきポイント・エラー対処

remove()で存在しない値を削除しようとしてエラーになる

❌ Before:remove()をそのまま使う

私が最初にセットを使ったとき、ユーザーのタグ一覧から特定のタグを削除する処理で、次のように書いていました。

tags = {"python", "web", "初心者"}
tags.remove("django")

「django」タグは実際には登録されていなかったため、実行時に次のエラーが発生しました。

KeyError: 'django'

リストのremove()ValueErrorでしたが、セットのremove()KeyErrorになる点にも戸惑いました。

✅ After:discard()を使うか、事前にin演算子で確認する

存在しない値を削除しようとしてもエラーにしたくない場合は、discard()を使います。

tags = {"python", "web", "初心者"}
tags.discard("django")
print(tags)
# {'python', 'web', '初心者'}

discard()は、値が存在しなくても何も起こらずに処理が続行されます。

エラーの発生自体をロジックとして使いたい場合はremove()、安全に処理を続けたい場合はdiscard()、という使い分けを覚えておくと安心です。

応用:集合演算の使い方

セットの真価は、数学の集合演算をそのままコードで表現できる点にあります。

set_a = {1, 2, 3, 4}
set_b = {3, 4, 5, 6}

和集合(どちらかに含まれる要素)

print(set_a | set_b)
# {1, 2, 3, 4, 5, 6}
print(set_a.union(set_b))
# {1, 2, 3, 4, 5, 6}

積集合(両方に共通する要素)

print(set_a & set_b)
# {3, 4}
print(set_a.intersection(set_b))
# {3, 4}

差集合(片方にしかない要素)

print(set_a - set_b)
# {1, 2}
print(set_a.difference(set_b))
# {1, 2}

例えば「昨日のログインユーザー」と「今日のログインユーザー」のセットを作り、差集合を取れば「今日だけ来たユーザー」を一瞬で求められます。

ループで比較処理を書くよりも、圧倒的に短く読みやすいコードになります。

まとめ

この記事のポイント

  • セットは{}またはset()で作成し、重複した値を持てない
  • 空のセットは{}ではなくset()で作成する
  • 要素の追加はadd()、削除はremove()またはdiscard()
  • remove()は存在しない値の削除でKeyErrorになるため注意する
  • 和集合|・積集合&・差集合-を使えば、重複比較の処理が簡潔に書ける

次に読むべき記事

データ構造の基本を一通り押さえたら、次は処理を再利用できる仕組みである「関数」の定義方法を学んでいきましょう。

→ 次の記事:関数の定義と引数(デフォルト引数・可変長引数)

タグ: Python, 初心者向け, 基本文法

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