【Python】set型:ユニークな(重複しない)要素の集合

2021.09.26 /

【Python】set型:ユニークな(重複しない)要素の集合

本記事ではPythonのデータ型の一つ、set型について解説していきます。

setはリストやタプルと同じように、複数の要素を保持するための型です。ユニークな要素の集合を保持します。

setはlistやtupleとは大きく異なる特徴を持っています。この特徴を知ることで、setを友好的にプログラムで利用できるようになります。

ぜひ本記事を通してset型の特徴や他のデータ型との違いについて理解してください。

set型とは

set型は複数の要素(集合)を保持するデータ型の一つです。

複数の要素を格納できるという点は、リスト型やタプル型と同じです。
しかしsetには以下の特徴を持っています。

  • 重複した要素の追加を許さない(ユニークな要素の集合である)
  • 要素の順序は保持しない(インデックスによるアクセス不可)
  • setはミュータブル(変更可能)なオブジェクト
  • ミュータブルなオブジェクトは保持できない(イミュータブルな要素のみ保持可能)
  • 要素をsetからランダムで取り出す(forループ、pop)
  • 集合計算が可能

setではすでに保持している要素を追加しようとしても、それは無視されます。setに保持される要素はすべてユニークな要素となります。

リストやタプルは同じ要素でも複数回追加できますし、順番も保持します。しかしsetは順序を保持しないため、何番目の要素を取り出すといった操作はできないです。

setによって数学の集合演算を行えるようになります。

setの操作方法

setのオブジェクト生成

setのオブジェクトを生成する方法を見ていきましょう。

setを生成する方法は次の2つあります。

  • 全体を{と}でくくり、要素はカンマで区切るシンタックスで生成
  • set関数を用いる

一つ目の生成方法は次のように記述します。

sets = {4, 5, "office", 54}

上記をset関数で表すと次のようになります。

sets = set([4, 5, "office", 54])

set関数にはリストやタプル、辞書などを渡してセットを生成することができます。
また格納するオブジェクトの種類は問いません。

空のセットを生成する場合は、set関数を使用する必要があります。

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

setは同じ要素は保持できないので、以下のようにsetを生成しても、生成したsetには同一の要素が保持されていないことがわかります。

sets = set([4, 5, "office", 54, 5, "office"])
print(sets)
# {4, 5, 54, 'office'}

このsetの特徴を利用すると、リストやタプルから重複した要素を除去することもできます。

setに要素を追加(addメソッド)

既存のsetに要素を追加するにはaddメソッドを使用します。

sets = set()
sets.add(5)
sets.add("office54")
sets.add(54)
print(sets)
# {'office54', 5, 54}

重要なことなので再度触れますが、セットは重複を許さないため、セットに既存の要素を追加しようとしても無視されます。

sets.add(5)
print(sets)
# {'office54', 5, 54}

すでに格納されている要素を追加しようとしたからといって、エラーが発生するわけではなく、ただ無視されるだけです。

setから要素を削除(remove、discard、clear)

既存のsetから特定の要素を削除するにはremoveメソッドを使用します。

sets = set()
sets.add(5)
sets.add("office54")
sets.remove(5)
print(sets)
# {'office54'}

setから存在しない要素を削除するとエラー(KeyError)が発生します。

discardメソッドも同様に指定した要素をsetから削除します。removeメソッドとは異なり、setに存在しない要素を指定してもエラー(KeyError)は発生しません。

セットすべてを破棄する場合はclearメソッドを使用します。

sets = set()
sets.add(5)
sets.add("office54")
sets.clear()
print(sets)
# set()

上記の結果からもわかるように、clearメソッドを使用すると空のセットになります。

setから要素を取り出す(forループ、pop)

setではリストのようにインデックスやスライスによるアクセスはできません。
なぜならsetは順序を持たないからです。

setに格納されている要素を取り出すには次の方法を使います。

  • forループによる列挙
  • popによる取り出し

注意点として、これらの方法で取り出される要素はランダムであるという点です。

sets = set()
sets.add(5)
sets.add("office54")
sets.add(4)
for i in sets:
    print(i)
# 結果:office54、4、5
print(sets.pop())
# 結果:office54(使用する毎に異なる)

setによる計算(和集合、差集合、積集合、排他的論理和集合)

setは数学の集合と同じような仕組みであるため、以下の集合計算ができます。

  • 和集合
  • 差集合
  • 積集合
  • 排他的論理和集合

これらの集合計算について見ていきましょう。

ここで利用するセット(集合)は以下のものとします。

set1 = set([1, 2, 3])
set2 = set([3, 4, 5])

和集合(union)

2つのリストから重複した要素を省いて1つのリストにしたいときってありますよね。そういったときはセットの和集合(ユニオン)を利用します。

和集合とは2つ以上のセット(集合)に含まれている要素をすべて含んだ集合です。

和集合の計算には次の演算子またはメソッドを使用します。

  • 「|(パイプ)」を使用する
  • unionメソッドを使用する

まず演算子を利用して、s1とs2の和集合unionを作成してみます。

union = set1 | set2
print(union)
# {1, 2, 3, 4, 5}

次にunionメソッドを利用して和集合unionを作成してみます。

union = set1.union(set2)
print(union)
# {1, 2, 3, 4, 5}

結果からわかるように、set1とset2で重複していた要素3は、和集合で一度のみしか出てきません。これはセットの特徴、「重複を許さない」からです。

差集合(diffrence)

差集合とは2つ以上のセット(集合)から、1つの集合のみに含まれている要素の集合です。

差集合の計算には次の演算子またはメソッドを使用します。

  • 「-(マイナス)」を使用する
  • differenceメソッドを使用する

まず演算子を利用して、s1とs2の差集合differenceを作成してみます。

difference = set1 - set2
print(difference)
# {1, 2}

次にdifferenceメソッドを利用して差集合differenceを作成してみます。

difference = set1.difference(set2)
print(difference)
# {1, 2}

結果からわかるように、set1とset2でset1のみに含まれている要素1、2だけが差集合に含まれています。

積集合(intersection)

2つのリストやセットから重複している要素のみを抽出したいときもよくあります。その場合は積集合(インターセクション)を利用します。

積集合とは2つ以上のセット(集合)から同一の要素をすべて含んだ集合です。

積集合の計算には次の演算子またはメソッドを使用します。

  • 「&(アンパサンド)」を使用する
  • intersectionメソッドを使用する

まず演算子を利用して、s1とs2の積集合intersectionを作成してみます。

intersection = set1 & set2
print(intersection)
# {3}

次にintersectionメソッドを利用して積集合intersectionを作成してみます。

intersection = set1.intersection(set2)
print(intersection)
# {3}

結果からわかるように、set1とset2で重複していた要素3のみが積集合に含まれています。

排他的論理和集合

排他的論理和集合とは2つのセット(集合)から同一の要素以外をすべて含んだ集合です。

排他的論理和集合の計算には次の演算子またはメソッドを使用します。

  • 「^(キャレット)」を使用する
  • symmetric_differenceメソッドを使用する

まず演算子を利用して、s1とs2の排他的論理和集合symmetricを作成してみます。

symmetric = set1 ^ set2
print(symmetric)
# {1, 2, 4, 5}

次にsymmetric_differenceメソッドを利用して排他的論理和集合symmetricを作成してみます。

symmetric = set1.symmetric_difference(set2)
print(symmetric)
# {1, 2, 4, 5}

結果からわかるように、set1とset2で重複していた要素3を除いたすべての要素の集合となっています。

list型からset型への変換

リストからセットへの変換は簡単にできます。
変換にはset関数を次のように利用します。

list = [1, 2, 4, 5, 54]
sets = set(list)
print(sets)
# {1, 2, 4, 5, 54}

set関数の引数にリストを渡すだけで、set型へ変換することができます。

リストから重複を削除したいときに、この変換を利用すれば、一発で重複を削除できます。

list = [1, 2, 4, 5, 54, 2, 5, 4, 6]
sets = set(list)
print(sets)
# {1, 2, 4, 5, 6, 54}

まとめ

本記事「【Python】set型:ユニークな(重複しない)要素の集合」はいかがでしたか。

setセット型はリストやタプルと違った利便性があります。setを使えるようになれば、開発の幅が広がることは間違いないです。

まだset型を使ったことがない方は、ぜひset型をご自身のプログラムで利用してみてください。