Pythonの基礎 - 集合の作成と操作
概要
Pythonにおける集合とは、辞書の値の無いキーだけの集まりのようなものである。
複数の集合に共通の要素があるのか、片方にあって片方に無いものは何かといった計算をすることができる。
集合の宣言
集合は要素を波括弧{}
で括って宣言する。
集合の要素には、同じ値が複数存在せず、ただ1つだけである。したがって、複数の同じ値を集合の要素に代入しても要素は整理される。
a = {1, 3, 5, 7, 9}
b = {1, 1, 1, 3, 5, 7, 8, 5, 6, 6, 3, 3, 9, 7}
print(type(a))
print(b)
# 出力
<class 'set'>
{1, 3, 5, 6, 7, 8, 9}
また、空集合は値を入れずに波括弧{}で括るのではなく、set関数で作成する。
以下の例では、aは辞書になる。(波括弧{}で括ることは、辞書も集合も同じ)
a = {}
b = set()
print(type(a))
print(type(b))
# 出力
<class 'dict'>
<class 'set'>
※注意点
集合型オブジェクトには、要素の順番が存在しない。
そのため、複数の要素が含まれている場合、どのような順序で並んでいるのかは不定である。
また、集合型オブジェクトには同じ値の要素は1つか格納できないため、同じ値を持つ要素は1つにまとめられる。
以下の例では、集合の要素として、"H" "a" "p" "p" "y"という5つの文字を要素として集合を作成している。
myset = {"H", "a", "p", "p", "y"}
print(myset)
# 出力
{'H', 'y', 'a', 'p'}
集合のメソッド
要素の追加
集合に要素を加えるには、add
関数を使用する。
x = set()
x.add(10)
x.add('Python')
print(x)
# 出力
{10, 'Python'}
要素の削除
また、集合の要素を削除するには、remove
関数を使用する。
集合に指定した値が存在しない場合、KeyError
エラーが発生する。
集合の要素を全て削除するには、clear
関数を使用する。
x = {3, 1, 5, 4, 2}
x.remove(5)
print(x)
x.clear()
print(x)
# 出力
{3, 1, 4, 2}
{}
discard
関数は、引数に指定した値を持つ要素を集合から削除する。
remove
関数と異なり、引数に指定した値が集合に存在しない場合でもエラーは発生しない。
colorset = {"Red", "Green", "Blue"}
colorset.discard("White")
print(colorset)
# 出力
{'Blue', 'Green', 'Red'}
要素の取得
pop
関数は、集合の中のいずれか1つの要素を削除して、その要素を返す。
ただし、どの要素を削除するかは指定することができない。
colorset = {"Red", "Green", "Blue"}
color = colorset.pop()
print(color)
print(colorset)
color = colorset.pop()
print(color)
print(colorset)
# 出力
Green
{'Blue', 'Red'}
Blue
{'Red'}
要素数の取得
len
関数は、引数に指定したオブジェクトの長さや要素の数を取得することができる。
len
関数の引数に集合を指定した場合は、集合に含まれる要素数を取得することができる。
len({"Red", "Green", "Blue"})
len(frozenset([1, 2, 3, 4, 5]))
# 出力
3
5
set関数を使用して集合に変換する
set関数を使用すれば、文字列、リスト、タプル、辞書から重複する要素を取り除いて集合を作成することができる。
以下の例では、重複した要素は整理されているのが分かる。
辞書型においては、キーが集合に変換されている。
a = set('PythonPython')
b = set(['Python', 'JavaScript', 'PHP', 'Python', 'JavaScript', 'Python'])
c = set(('Python', 'JavaScript', 'PHP', 'C', 'JavaScript', 'Ruby', 'Swift'))
d = set({'x':100, 'y':200, 'z':300})
# 出力
{'P', 'y', 't', 'h', 'o', 'n'}
{'Python', 'JavaScript', 'PHP'}
{'Python', 'JavaScript', 'PHP', 'C', 'Ruby', 'Swift'}
{'x', 'y', 'z'}
リストから集合を生成するには、set型またはfrozenset型のオブジェクト生成時にリストを引数に指定する。
mylist = ["A", "B", "C"] # リストの生成
myset = set(mylist) # リストから集合を生成
print(myset)
# 出力
{'B', 'C', 'A'}
タプルから集合を作成するには、set型またはfrozenset型のオブジェクト生成時にタプルを引数に指定する。
mytuple = ("A", "B", "C") # タプルの生成
myset = set(mytuple) # タプルから集合を生成
print(myset)
# 出力
{'B', 'C', 'A'}
range
型から集合を作成するには、set型またはfrozenset型のオブジェクト生成時に、range
型のオブジェクトを引数に指定する。
range
型とは、コンストラクタで引数に指定した開始値から終了値までの連続した数値を持つオブジェクトのことである。
開始値から終了値までの連続した数値を要素として持つ。開始値を省略した場合は、0
が開始値となる。
class range(<終了値>) class range(<開始値>, <終了値>[, <ステップ値>])
myset = set(range(10))
print(myset)
# 出力
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
集合の演算
積集合
積集合は、両方の集合に共通する要素からなる集合である。
アンパサンド&
またはintersection
関数を使用して求めることができる。
a = {1, 2, 3}
b = {2, 3, 4}
c = a & b
d = a.interseciton(b)
a.intersection_update(b)
print(a)
print(c)
print(d)
# 出力
{2, 3}
{2, 3}
{2, 3}
和集合
和集合は、少なくともどちらかの集合に要素が含まれている集合である。
バーティカルバー|
またはunion
関数を使用して求めることができる。
a = {1, 2, 3}
b = {2, 3, 4}
c = a | b
d = a.union(b)
a.update(b)
print(a)
print(c)
print(d)
# 出力
{1, 2, 3, 4}
{1, 2, 3, 4}
{1, 2, 3, 4}
差集合
差集合は、一方には含まれているがもう一方には含まれていない要素の集合である。
マイナス-
またはdifference
関数で求めることができる。
a = {1, 2, 3}
b = {2, 3, 4}
c = a - b
d = a.difference(b)
a.difference_update(b)
print(a)
print(c)
print(d)
# 出力
{1}
{1}
{1}
XOR (対称差集合)
XORは、どちらか片方に含まれるが両方には含まれない要素の集合である。
キャレット^
またはsymmetric_difference
関数で求めることができる。
a = {1, 2, 3}
b = {2, 3, 4}
c = a ^ b
d = a.symmetric_difference(b)
a.symmetric_difference_update(b)
print(a)
print(c)
print(d)
# 出力
{1, 4}
{1, 4}
{1, 4}
集合と他の集合との関係
集合と集合が等しいかどうか、また、集合が他の集合の部分集合かどうか等、集合と他の集合との関係を確認する方法について記載する。
集合が他の集合と等しいかどうか
比較演算子の==
または!==
で比較することができる。
集合Aの要素が集合Bに全て含まれており、集合Bの要素が集合Aに全て含まれている場合、Trueとなる。
set1 = {"A", "B", "C"}
set2 = {"B", "C", "A"}
print(set1 == set2)
# 出力
True
部分集合
比較演算子の<=
およびissubset
関数で比較することができる。
集合Aの要素が全て集合Bに含まれている場合、集合Aは集合Bの部分集合であるという。
以下の例では、集合set1は集合set2の部分集合であるが、集合set2は集合set1の部分集合ではない。
集合set1と集合set3が等しい場合いおいても、集合set1は集合set3の部分集合となる。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"B", "A"}
print(set1 <= set2)
print(set2 <= set1)
print(set1 <= set3)
print(set1.issubset(set2)) # 集合set1が集合set2の部分集合の場合、Trueとなる
# 出力
True
False
True
True
真部分集合
比較演算子の<
で比較することができる。
集合Aの要素が全て集合Bに含まれており、かつ、集合Aと集合Bが等しくない場合、集合Aは集合Bの真部分集合であるという。
以下の例では、集合set1は集合set2の真部分集合であり、集合set1と集合set3は真部分集合ではない。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"A", "B"}
print(set1 < set2)
print(set2 < set1)
print(set1 < set3)
# 出力
True
False
False
超集合
比較演算子の>=
およびissuperset
関数で比較することができる。
集合Bの要素が全て集合Aに含まれている場合、集合Aは集合Bの超集合であるという。
以下の例では、集合set1は集合set2の超集合ではないが、集合set2は集合set1の超集合である。
集合set1と集合set3が等しい場合も、集合set1は集合set3の超集合となる。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"B", "A"}
print(set1 >= set2)
print(set2 >= set1)
print(set1 >= set3)
print(set3 >= set1)
print(set2.issuperset(set1))
# 出力
False
True
True
True
True
真超集合
比較演算子の>
で比較することができる。
集合Bの要素が全て集合Aに含まれており、かつ、集合Aと集合Bが等しくない場合、集合Aは集合Bの真超集合であるという。
以下の例では、集合set1は集合set2の真超集合ではないが、集合set2は集合set1の真超集合である。
また、集合set1と集合set3が等しい場合も真超集合ではない。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"A", "B"}
print(set1 > set2)
print(set2 > set1)
print(set1 > set3)
# 出力
False
True
False
互いに素
set型およびfrozenset型にあるisdisjoint
関数で比較することができる。
集合Aと集合Bが同じ要素を1つも持たない時、集合Aは集合Bと互いに素であるという。
以下の例では、集合set1は集合set2は共通の要素がないので互いに素であるが、
集合set1と集合set3、および、集合set2と集合set3は共通する要素があるため互いに素ではない。
set1 = {"A", "B"}
set2 = {"C", "D", "E"}
set3 = {"A", "C"}
print(set1.isdisjoint(set2))
print(set1.isdisjoint(set3))
print(set2.isdisjoint(set3))
# 出力
True
False
False
集合に指定した値と同じ要素が含まれているか確認する
集合に対して、指定した値と同じ要素が含まれているかどうか確認する方法について記載する。
要素が含まれているかどうかを確認するには、in
演算子またはnot in
演算子を使用する。
in
演算子は、集合の要素に指定した値と同じ値の要素が存在する場合はTrue
、存在しない場合はFalse
となる。
not in
演算子は、集合の要素に指定した値と同じ値の要素が存在しない場合はTrue
、存在する場合はFalse
となる。
myset = {"A", "B", "C"}
print("A" in myset)
print("D" in myset)
print("D" not in myset)
# 出力
True
False
True