Pythonで複数の辞書のキーに対する集合演算(共通、和、差、対称差)
Pythonで辞書(dict
型オブジェクト)のメソッドkeys()
とitems()
を使うと、キーkey
およびキーと値value
のタプルに対して集合演算が可能。
キーと値のタプルから辞書を生成することができるので、例えば、複数の辞書に共通する要素(キーと値)からなる辞書を生成したりできる。
例として以下の二つの辞書オブジェクトを使う。
d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'b': 2, 'c': 4, 'd': 5}
- 辞書オブジェクトの
keys()
メソッドとitems()
メソッド - 複数の辞書に共通のキーを抽出(共通部分)
- 複数の辞書に含まれるキーをすべて抽出(和集合)
- 複数の辞書のいずれかにのみ含まれるキーを抽出(差集合、対称差集合)
辞書オブジェクトのkeysメソッドとitemsメソッド
辞書オブジェクトにはkeys()
メソッドとitems()
メソッドがある。
keys()
はキーkey
の、items()
はキーと値value
のタプル(key, value)
のビューを返す。
print(list(d1.keys()))
# ['a', 'b', 'c']
print(type(d1.keys()))
# <class 'dict_keys'>
print(list(d1.items()))
# [('a', 1), ('b', 2), ('c', 3)]
print(type(d1.items()))
# <class 'dict_items'>
それぞれdict_keys
型、dict_items
型だが、set
型のような集合演算をサポートしている。
辞書オブジェクトには値value
のビューを返すvalues
メソッドもあるが、値value
は重複する場合があるので集合演算はサポートされていない。
以下、keys()
メソッドとitems()
メソッドを利用した集合演算の例を示す。
複数の辞書に共通のキーを抽出(共通部分)
複数の辞書に共通しているキーはkeys()
メソッドと&
演算子で抽出できる。
intersection_keys = d1.keys() & d2.keys()
print(intersection_keys)
# {'c', 'b'}
集合演算の結果はset
型。以降の例でも同じ。
print(type(intersection_keys))
# <class 'set'>
items()
メソッドの場合、キーと値が両方とも共通のものが抽出される。キーのみ、あるいは、値のみが共通のものは除外される。
intersection_items = d1.items() & d2.items()
print(intersection_items)
# {('b', 2)}
辞書オブジェクトのコンストラクタdict()
にタプル(key, value)
の集合(items()
メソッドの集合演算結果)を渡すと辞書を生成することが可能。
intersection_dict = dict(d1.items() & d2.items())
print(intersection_dict)
# {'b': 2}
print(type(intersection_dict))
# <class 'dict'>
複数の辞書に含まれるキーをすべて抽出(和集合)
複数の辞書に含まれるすべてのキー、つまり、複数の辞書のいずれかに少なくとも一つ含まれるキー(和集合)は|
演算子で抽出できる。
union_keys = d1.keys() | d2.keys()
print(union_keys)
# {'d', 'a', 'b', 'c'}
items()
メソッドの場合は以下の通り。キーが共通でも値が異なる要素は別々に抽出される。
union_items = d1.items() | d2.items()
print(union_items)
# {('d', 5), ('c', 4), ('a', 1), ('b', 2), ('c', 3)}
この例のようにキーが共通で値が異なるタプルがあると、その集合から辞書を生成する場合にどちらか一方のみが残るが、いずれの値が残るかは指定できない。
union_dict = dict(d1.items() | d2.items())
print(union_dict)
# {'d': 5, 'c': 3, 'a': 1, 'b': 2}
複数の辞書のいずれかにのみ含まれるキーを抽出(差集合、対称差集合)
複数の辞書のいずれか一方にのみ含まれるキー(対称差集合)は^
演算子で抽出できる。
symmetric_difference_keys = d1.keys() ^ d2.keys()
print(symmetric_difference_keys)
# {'d', 'a'}
items()
メソッドの場合は以下の通り。|
演算子(和集合)と同様に、キーが共通でも値が異なる要素は別々に抽出される。
symmetric_difference_items = d1.items() ^ d2.items()
print(symmetric_difference_items)
# {('d', 5), ('c', 4), ('a', 1), ('c', 3)}
この例のようにキーが共通で値が異なるタプルがあると、その集合から辞書を生成する場合にどちらか一方のみが残るが、いずれの値が残るかは指定できない。
symmetric_difference_dict = dict(d1.items() ^ d2.items())
print(symmetric_difference_dict)
# {'d': 5, 'c': 3, 'a': 1}
-
演算子で差集合を取得することもできる。
difference_keys = d1.keys() - d2.keys()
print(difference_keys)
# {'a'}
difference_items = d1.items() - d2.items()
print(difference_items)
# {('c', 3), ('a', 1)}
difference_dict = dict(d1.items() - d2.items())
print(difference_dict)
# {'c': 3, 'a': 1}