集合

基本

集合はユニークな(重複のない)要素をまとめて保持する.「値」のない辞書と考えると分かりやすいかもしれない.

S = {'東京', '神奈川', '千葉', '埼玉'}
S
{'千葉', '埼玉', '東京', '神奈川'}
type(S)
set
len(S)
4

集合に要素が含まれているかどうかin演算子で調べることができる.

'東京' in S
True
'栃木' in S
False

集合に要素を追加するには,addメソッドを用いる.

S.add('栃木')
'栃木' in S
True

集合から要素を削除するには,removeメソッドを用いる.

S.remove('栃木')
'栃木' in S
False

集合の要素になっていないものをremoveメソッドで取り除こうとすると,エラーになる.

S.remove('栃木')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-11-eb5e5ba43ebe> in <module>
----> 1 S.remove('栃木')

KeyError: '栃木'

集合の要素になっているときだけ削除するには,discardメソッドを用いる.

S.discard('栃木')

要素が空の集合(空集合)はset関数で作成する({}は辞書となってしまうため,集合とは異なるオブジェクトになってしまう).

S = set()
S
set()

集合の内包表記

九九の3の段を表現する集合オブジェクトを作成してみる.

m3 = set()
for i in range(10):
    m3.add(i * 3)
m3
{0, 3, 6, 9, 12, 15, 18, 21, 24, 27}

このオブジェクトは,次のように集合の内包表記で構築することもできる.「i times 3 for all i in the range of ten」のように英語読みすると分かりやすいかもしれない.

m3n = {i*3 for i in range(10)}
m3n
{0, 3, 6, 9, 12, 15, 18, 21, 24, 27}

また,「0から29の範囲の中で3で割ったあまりが0になる数字の集合」というアイディアに基づいた実装をすると,以下のようになる.

m3nn = {i for i in range(30) if i % 3 == 0}
m3nn
{0, 3, 6, 9, 12, 15, 18, 21, 24, 27}

集合の内包表記をネストさせることで,九九で出てくる数字を表す集合を作成できる.

M = {i*j for j in range(10) for i in range(10)}
M
{0,
 1,
 2,
 3,
 4,
 5,
 6,
 7,
 8,
 9,
 10,
 12,
 14,
 15,
 16,
 18,
 20,
 21,
 24,
 25,
 27,
 28,
 30,
 32,
 35,
 36,
 40,
 42,
 45,
 48,
 49,
 54,
 56,
 63,
 64,
 72,
 81}

集合間の演算

\(1\)以上\(n\)以下の自然数を\(\mathbb{N}_n\)と書くことにする.\(1\)以上\(30\)以下の\(2\)の倍数と\(3\)の倍数を表す集合はそれぞれ,

\[\begin{split} M_2 = \{i \in \mathbb{N}_{30} \mid i \equiv 0 \pmod{2} \} \\ M_3 = \{i \in \mathbb{N}_{30} \mid i \equiv 0 \pmod{3} \} \end{split}\]

と書ける.\(\mathbb{N}_{30}\)\(M_2\)\(M_3\)をそれぞれ,集合型のオブジェクトNM2M3で表す.

N = set(range(1, 31))
M2 = {i for i in N if i % 2 == 0}
M3 = {i for i in N if i % 3 == 0}
M2
{2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}
M3
{3, 6, 9, 12, 15, 18, 21, 24, 27, 30}

\(M_2\)\(M_3\)の積集合\(M_2 \cap M_3\)&演算子で求められる.

M2 & M3
{6, 12, 18, 24, 30}

\(M_2\)\(M_3\)の和集合\(M_2 \cup M_3\)|演算子で求められる.

M2 | M3
{2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 26, 27, 28, 30}

\(\mathbb{N}_{30}\)\(M_2\)の差集合\(\mathbb{N}_{30} \setminus M_2\)-演算子で求められる.

N - M2
{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29}

\(M_2\)\(M_3\)のいずれか一方に含まれる要素を集めた集合は^演算子で求められる.

M2 ^ M3
{2, 3, 4, 8, 9, 10, 14, 15, 16, 20, 21, 22, 26, 27, 28}

2つの集合が部分集合の関係にあるかどうかは,<演算子で調べられる.

M2 < N
True
M2 < M3
False

2つの集合の要素が全て等しい/等しくないかは,==演算子および!=演算子で調べられる.

X = set(range(2, 31, 2))
X
{2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}
X == M2
True
X != M2
False
X == M3
False
X != M3
True