TL;DR
集合は一意な要素の集合を扱うイテラブル(繰り返し可能)オブジェクトである。個々のキーはユニークである必要がある。重複を排除しユニークな要素だけ抽出したいときに便利に使えるだろう。
集合のポイント
- 要素の重複を排除する
- 要素の順番を保持しないのでインデックスアクセスは不可
- set 型と frozenset 型がある
- set 型は可変、frozenset 型は不変
- 空の場合は偽、要素が一つでもあれば真
集合は、組み込み関数である set()関数を使うか、{}
で作る。実は{}
で作られるのは空辞書である。
empty_set = set()
empty_set
# set()
even_n = {2, 4, 6, 8}
even_n
# {2, 4, 6, 8}
順番を保持しないので、添字によるアクセスはできない。
lang = {'Python', 'Go', 'Rust', 'JavaScript'}
lang[1]
# TypeError: 'set' object is not subscriptable
set 型
set 型は可変なオブジェクトであり、一意な要素の集合を扱う。重複する要素は一つになる。
重複する要素は排除され、一つにまとめられる。リスト、文字列、タプル、辞書から重複する値を取り除くことができる。
set([1, 2, 3, 3, 4, 5, 5])
set((1, 2, 3, 3, 4, 5, 5))
set({1, 2, 3, 3, 4, 5, 5})
# ↑は全て {1, 2, 3, 4, 5} が返る
set('hello')
# {'e', 'h', 'l', 'o'}
set.add()
set.add()は、set 型に要素を追加するメソッドである。
lang = {'Python', 'Go', 'Rust', 'JavaScript'}
lang.add('Java')
lang
# {'Go', 'Java', 'JavaScript', 'Python', 'Rust'}
set.remove()
set.remove()は、要素を指定して削除するメソッドである。
lang = {'Python', 'Go', 'Rust', 'JavaScript'}
lang.remove('JavaScript')
lang
# {'Go', 'Python', 'Rust'}
len()
要素の数を数えるときは、len() を使う。
lang = set(('Python', 'Go', 'Rust', 'Java'))
len(lang)
# 4
for in
集合は for 文で反復可能である。ユニークな要素に何か付与したい場合などに使う。次のコードは、重複なしの要素に数字を付けて返すものである。
lang = set(('Python', 'Go', 'Rust', 'Java', 'Python'))
for count, i in enumerate(lang, start=1):
print(f'言語{count}:{i}')
# 言語1:Rust
# 言語2:Go
# 言語3:Java
# 言語4:Python
frozenset 型
frozenset 型は、set 型を不変にした型である。不変なので要素の変更(add、remove など)はできない。
lang = frozenset(('Python', 'Go', 'Rust', 'Java'))
lang.remove('Go')
# AttributeError: 'frozenset' object has no attribute 'remove'
集合演算
和集合
和集合の演算を行う場合は|
か set.union()を使う。両方に含まれる要素が返される。重複する要素はない。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
frontend = {'JavaScript', 'html', 'css'}
backend | frontend
# {'Go', 'JavaScript', 'Python', 'Rust', 'css', 'html'}
set.union() も |
と同じ結果になる。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
frontend = {'JavaScript', 'html', 'css'}
backend.union(frontend)
# {'Go', 'JavaScript', 'Python', 'Rust', 'css', 'html'}
差集合
差集合の演算を行う場合は-
か set.difference()を使う。対象となる集合の中から指定の集合に属する要素を取り去る。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
ng = {'JavaScript', 'html', 'css'}
backend - ng
# {'Go', 'Python', 'Rust'}
set.difference() も -
と同じ結果になる。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
ng = {'JavaScript', 'html', 'css'}
backend.difference(ng)
# {'Go', 'Python', 'Rust'}
積集合
積集合の演算を行う場合は&
か set.intersection()を使う。共通の要素を取り出す。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
frontend = {'JavaScript', 'html', 'css'}
backend & frontend
# {'JavaScript'}
set.intersection() も &
と同じ結果になる。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
frontend = {'JavaScript', 'html', 'css'}
backend.intersection(frontend)
# {'JavaScript'}
対称差
積集合の演算を行う場合は^
か set.symmetric_difference()を使う。どちらか一方だけに属する要素だけが返る。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
frontend = {'JavaScript', 'html', 'css'}
backend ^ frontend
# {'Go', 'Python', 'Rust', 'css', 'html'}
set.symmetric_difference() も ^
と同じ結果になる。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
frontend = {'JavaScript', 'html', 'css'}
backend.symmetric_difference(frontend)
# {'Go', 'Python', 'Rust', 'css', 'html'}
部分集合
部分集合か判定する場合は<=
か issubset()を使う。片方の集合が、もう片方の部分集合になっているか判定する。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
frontend = {'JavaScript'}
frontend <= backend
# True
set.issubset() も <=
と同じ結果になる。
backend = {'Python', 'Go', 'Rust', 'JavaScript'}
frontend = {'JavaScript'}
frontend.issubset(backend)
# True