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

当サイトではアフィリエイトプログラムを利用して商品を紹介しています。

setオブジェクト

setクラスのオブジェクト は [コンテナ型 – 集合型] に分類されます。長さをもち、要素を追加・変更・削除できるなど、コンテナとしての機能は list オブジェクト と共通していますが、リストと大きく異なるのは要素が順番をもたない要素が重複しないという2点です。また、set オブジェクトは要素の変更が可能な mutable なオブジェクト です。
 
サンプルコードで set の特徴を確認してみましょう。
set を定義するときは要素を { } で囲みます。

# PYTHON_SET

# In[1]

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

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

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

演算子による集合演算

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

和集合

集合 A と集合 B の和集合 C は、A の要素と B の要素をすべて含みます(ただし、A と B に重複した要素があるときは1つは捨てられます)。数学記号では A ∪ B で表される集合です。
 
set 集合演算による和集合
 
set 型データの和集合を得るときは「 | 」という演算子を用います。

# PYTHON_SET_OPERATION

# In[1]

# 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 型データの共通部分を得るには演算子「 & 」を用います。

# PYTHON_SET_INTERSECTION

# In[1]

# 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 では「 – 」という演算子を使って差集合をつくります。
自然数の集合から偶数の集合を引いて、奇数の集合をつくってみます。

# PYTHON_SET_DIFFERENCE

# 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 でべき乗を計算する演算子は「 ** 」です)。

# PYTHON_SET_SYMMETRIC_DIFFERENCE

# In[1]

# 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 をつくっています。

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

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

set.union():和集合を生成

setA.union(setB) は setA と setB の和集合を返します。setA | setB と同じです。このメソッドの使用によって setA は書き換えられません。

# PYTHON_SET_UNION

# In[1]

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

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

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

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

 setA.intersection(setB) は set の共通部分(交わり)を返します。setA & setB と同じです。このメソッドの使用によって setA は書き換えられません。

# PYTHON_SET_INTERSECTION

# In[1]

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

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

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

set.difference():差集合を生成

 setA.difference(setB) は setA から setB に含まれる要素を除いた集合(差集合)を返します。setA – setB と同じです。このメソッドの使用によって、setA は書き換えられません。

# PYTHON_SET_DEFFERENCE_METHOD

# In[1]

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

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

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

set.symmetric_difference():対称差を生成

setA.symmetric_difference(setB) は setA と setB のどちらか片方のみに含まれる集合(対称差)を返すメソッドです。setA ^ setB と同じです。このメソッドの使用によって setA は書き換えられません。

# PYTHON_SET_SYMMETRIC_DIFFERENCE_METHOD

# In[1]

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

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

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

コメント

  1. HNaito より:

    「set.uinion( )」、「set.intersection( )」、「set.difference( )」、「set.symmetric_difference( )」において、
    「setAは書き換えられません」、「このメソッドの仕様によって setA は書き換えられません」→
    「このメソッドの使用によって setA は書き換えられません」に統一したほうが、わかりやすいと思いました。