setオブジェクトと集合演算

setオブジェクトと集合演算

set 型オブジェクト

 set クラスのオブジェクト は [コンテナ型 - 集合型] に分類されます。

 長さをもち、要素を追加・変更・削除できるなど、コンテナとしての機能は list オブジェクト と共通していますが、リストと大きく異なるのは 要素が順番をもたない要素が重複しない という2点です。また、set オブジェクトは要素の変更が可能な mutable なオブジェクト です。集合型にはもうひとつ、frozenset という immutable なオブジェクトも用意されています。

 サンプルコードで set の特徴を確認してみます。
 set を定義するときは要素を { } で囲みます。

#週間天気予報(日曜日~土曜日)
weather = {"晴れ", "くもり", "晴れ", "くもり", "雨", "雨", "晴れ"}

print(weather)
{'くもり', '晴れ', '雨'}

 週間天気予報のデータを作ろうと思いましたが、重複する要素はすべて消されてしまっています。set では要素の重複が認められていないので、この種のデータを扱うことはできません。特定のグループの身長や体重、試験の点数や偏差値といった統計的な数値データも重複の可能性があるので set で扱うことは避けてください。上のサンプルコードにあるように、set は重複した要素をもつデータを取り込んでも、エラーを返さずに、勝手に重複した要素を削除して集合を作ってしまいます。このような特徴があるために、リストやタプルなど他のコンテナに比べて扱えるデータに強い制限がかかるのですが、set には他のコンテナにはない、強力な演算機能があります。
 

演算子による集合演算

 set は数学の 集合演算 を行なうために設計されています。学校で A ∩ B とか A ∪ B というような記号の使い方を学んだ記憶があると思います。「もう、うんざりだよ」と思うかもしれませんが、プログラミングでは集合演算を避けては通れないので、基本的な部分だけ理解するようにしてください。

和集合

 集合 A と集合 B の和集合 C は、A の要素と B の要素をすべて含みます(ただし、A と B に重複した要素があるときは1つは捨てられます)。数学記号では A ∪ B で表される集合です。

 set 集合演算による和集合

 set 型データの和集合を得るときは「 | 」という演算子を用います。

# 30 以下の 3 の倍数
multiple_3 = {3, 6 , 9, 12, 15, 18, 21, 24, 27, 30}

# 30 以下の 5 の倍数
multiple_5 = {5, 10, 15, 20, 25, 30}

# 30 以下の自然数のうち、3 または 5 で割り切れる数
multiple_15 = multiple_3 | multiple_5

# 要素の個数
n = len(multiple_15)

print(multiple_15)
print("要素の個数:{}".format(n))
{3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24, 25, 27, 30}
要素の個数:14

 3 の倍数と 5 の倍数を重複しないように集めて multiple_15 という変数に入れています。
 要素の個数は len関数を使って求めています。
 

共通部分(交わり)

 集合 A と集合 B の共通部分(交わり) C は、A と B が共通にもつ要素を集めたものです。数学記号では A ∩ B で表される集合です。

 set 集合演算による共通部分(交わり)

 set 型データの共通部分を得るには演算子「 & 」を用います。

# 30 以下の 3 の倍数
multiple_3 = {3, 6 , 9, 12, 15, 18, 21, 24, 27, 30}

# 30 以下の 5 の倍数
multiple_5 = {5, 10, 15, 20, 25, 30}

# 30 以下の 15 の倍数
multiple_15 = multiple_3 & multiple_5

# 要素の個数
n = len(multiple_15)

print(multiple_15)
print("要素の個数:{}".format(n))
{30, 15}
要素の個数:2

 3 の倍数と 5 の倍数の共通部分は、3 と 5 の最小公倍数 15 の倍数です。
 

差集合

 集合 A から集合 B に含まれる要素を取り除いた集合を 差集合 とよび、数学では A\B という記号で表します。

set 集合演算による差集合

 Python では「 - 」という演算子を使って差集合をつくります。
 自然数の集合から偶数の集合を引いて、奇数の集合をつくってみます。

# 9 以下の自然数の集合
natural_num = {1, 2, 3, 4, 5, 6, 7, 8, 9}

# 9 以下の偶数の集合
even_num = {2, 4, 6, 8}

# 9 以下の奇数の集合
odd_num = natural_num - even_num

# 要素の個数
n = len(odd_num)

print(odd_num)
print("要素の個数:{}".format(n))
{1, 3, 5, 7, 9}
要素の個数:5

 

対称差

 集合 A と集合 B の和集合から集合 A と集合 B の共通部分を差し引いた集合 C を A と B の 対称差 とよび、数学では A △ B という記号で表します。すなわち

  A △ B = (A ∪ B) - (A ∩ B)

によって定義される集合です。

 set 集合演算による対称差

 Python では「 ^ 」という演算子を用いて対称差をつくります(他の言語では「 ^ 」という記号がべき乗演算に使われていることもあるので注意が必要です。エクセルもそうですよね。私も何度か間違えました。ちなみに Python でべき乗を計算する演算子は「 ** 」です)。

# 1 から 7 の自然数
myset_A = {1, 2, 3, 4, 5, 6, 7}

# 3 ~ 9 の自然数
myset_B = {3, 4, 5, 6, 7, 8, 9}

# 対称差をつくります
myset_C = myset_A ^ myset_B

# 要素の個数
n = len(myset_C)
print(myset_C)
print("要素の個数:{}".format(n))
{1, 2, 8, 9}
要素の個数 : 4

 このコードでは、A と B に含まれるすべての要素から、A と B に共通する要素 {3, 4, 5, 6, 7} を省いた残りの要素 {1, 2, 8, 9} で集合 C をつくっています。
 

アルゴリズム図鑑 絵で見てわかる26のアルゴリズム

中古価格
¥2,011から
(2019/7/30 20:26時点)

メソッドを用いた集合演算

 演算子の代わりに set オブジェクトのメソッドを用いても和集合・共通部分・差集合・対称差を得ることができます。以下に集合演算に使用するメソッドの簡単な解説とサンプルコードを載せておきます。メソッドの記述方式にある setA と setB は setオブジェクトを表します。

set.union() 和集合を生成

 union()メソッドは set と set2 の和集合を返します。

 setA.union (setB)

 setA | setB と同じです。setA は書き換えられません。

# 木星の衛星 A
J_sat_A = {"メティス", "アドラステア", "イオ", "エウロパ"}

# 木星の衛星 B
J_sat_B = {"イオ", "エウロパ", "ガニメデ", "カリスト"}

J_sat_A.union(J_sat_B)
{'アドラステア', 'イオ', 'エウロパ', 'カリスト', 'ガニメデ', 'メティス'}

 

set.intersection() 共通部分(交わり)を生成

 intersection()メソッドは setA と setB の共通部分(交わり)を返します。

 setA.intersection (setB)

 setA & setB と同じです。このメソッドの仕様によって setA は書き換えられません。

# 木星の衛星 A
J_sat_A = {"エウボリエ", "コレー", "ヘゲモネ", "パシテー"}

# 木星の衛星 B
J_sat_B = {"エウボリエ", "コレー", "メガクレテ", "アイモネ"}

J_sat_A.intersection(J_sat_B)
{'エウボリエ', 'コレー'}

 

set.difference() 差集合を生成

 difference()メソッドは setA から setB に含まれる要素を除いた集合(差集合)を返します。

 setA.difference (setB)

 setA - setB と同じです。setA は書き換えられません。

# 木星の衛星 A
J_sat_A = {"メティス", "アドラステア", "イオ", "エウロパ"}

# 木星の衛星 B
J_sat_B = {"イオ", "エウロパ", "ガニメデ", "カリスト"}

J_sat_A.difference(J_sat_B)
{'アドラステア', 'メティス'}

 

set.symmetric_difference() 対称差を生成

 symmetric_difference()メソッドは setA と setB のどちらか片方のみに含まれる集合(対称差)を返します。

 setA.symmetric_difference (setB)

 setA ^ setB と同じです。setA は書き換えられません。

# 木星の衛星 A
J_sat_A = {"エウボリエ", "コレー", "ヘゲモネ", "パシテー"}

# 木星の衛星 B
J_sat_B = {"エウボリエ", "コレー", "メガクレテ", "アイモネ"}

J_sat_A.symmetric_difference(J_sat_B)
{'アイモネ', 'パシテー', 'ヘゲモネ', 'メガクレテ'}