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}
Last Updated: 6/26/2019, 10:34:03 PM