キーと値のタプルを含む次の python 辞書があります。
{(A, 1): (B, 2),
(C, 3): (D, 4),
(B, 2): (A, 1),
(D, 4): (C, 3),
}
キーと値の組み合わせの一意のセットを取得するにはどうすればよいですか? そのようなこと(A,1):(B,2)
はありません(B,2):(A,1)
か?
キーと値のタプルを含む次の python 辞書があります。
{(A, 1): (B, 2),
(C, 3): (D, 4),
(B, 2): (A, 1),
(D, 4): (C, 3),
}
キーと値の組み合わせの一意のセットを取得するにはどうすればよいですか? そのようなこと(A,1):(B,2)
はありません(B,2):(A,1)
か?
d = {('A', 1): ('B', 2),
('C', 3): ('D', 4),
('B', 2): ('A', 1),
('D', 4): ('C', 3),
}
>>> dict(set(frozenset(item) for item in d.items()))
{('A', 1): ('B', 2), ('D', 4): ('C', 3)}
これは、ディクショナリ内の各キーと値のペアをセットに変換することによって機能します。これは重要です。どのペア(a, b)
でset([a, b])
も は に等しいからset([b, a])
です。したがって、これらのキー/値セットをすべて取得してセットに追加できれば、すべての重複を排除できれば完璧です。このset
型はハッシュ可能ではないため、これを行うことはできませんfrozenset
。代わりに使用します。組み込みdict()
関数は、反復可能なキー/値のペアを引数として受け入れることができるため、キー/値のペアのセットを渡すことができ、期待どおりに機能します。
d[('A', 1)] = ('A', 1)
これについてのコメントで、何かがそれ自体にマップされている場合に問題が発生するという素晴らしい点が指摘されましsorted()
た。
d = {('A', 1): ('A', 1),
('C', 3): ('D', 4),
('D', 4): ('C', 3),
}
>>> dict(sorted(item) for item in d.items())
{('A', 1): ('A', 1), ('C', 3): ('D', 4)}
これには、重複の場合、ソートされた順序が一貫して「小さい」要素をキーとして、「大きい」要素を値として与えるという利点もあります。
sorted()
ただし、Python 3.x では、イテラブル内のすべての要素が同じ型でない限り例外が発生するため、キーと値の型が異なる場合は注意が必要です。
>>> d = {1: 'A', 'A': 1}
>>> dict(sorted(item) for item in d.items())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
TypeError: unorderable types: int() < str()
さらに別の方法として:
original_dict = {('A', 1): ('B', 2),
('C', 3): ('D', 4),
('B', 2): ('A', 1),
('D', 4): ('C', 3),
}
new_dict = {}
for a in original_dict.items():
if a[0] > a[1]:
one, two = a[1],a[0]
else:
one,two = a[0],a[1]
new_dict[one] = two