[英]Return a set of pairs of keys from a dictionary that have a common value
我該如何編寫一個函數,該函數需要一個字典並返回一個包含至少有一個公共值的鍵對的集合?
例:
我有以下字典:
dict = {
'C': {'123'},
'A': {'123', '456'},
'D': {'123'},
'B': {'789', '456'},
'E': {'789'}}
MyFunction(dict)應該返回我:
{("A", "B"), ("A", "C"), ("A", "D"), ("B", "E"), ("C", "D")}
from itertools import combinations
d = {
'C': {'123'},
'A': {'123', '456'},
'D': {'123'},
'B': {'789', '456'},
'E': {'789'}
}
def MyFunction(d):
out = set()
for i, j in combinations(d, 2):
if d[j].intersection(d[i]) and (i, j) not in out and (j, i) not in out:
out.add((i, j))
return set(tuple(sorted(i)) for i in out)
print(MyFunction(d))
print(MyFunction(d) == {("A", "B"), ("A", "C"), ("A", "D"), ("B", "E"), ("C", "D")})
輸出為:
{('A', 'D'), ('A', 'B'), ('B', 'E'), ('A', 'C'), ('C', 'D')}
True
如果您認為('A', 'C')
和('C', 'A')
相同,則可以替換
return set(tuple(sorted(i)) for i in out)
只是
return out
defaultdict
+ combinations
對於蠻力解決方案,您可以反轉集合字典,然后使用集合理解:
from collections import defaultdict
from itertools import combinations
d = {'C': {'123'}, 'A': {'123', '456'},
'D': {'123'}, 'B': {'789', '456'},
'E': {'789'}}
dd = defaultdict(set)
for k, v in d.items():
for w in v:
dd[w].add(k)
res = {frozenset(i) for v in dd.values() if len(v) >= 2 for i in combinations(v, 2)}
print(res)
{frozenset({'A', 'D'}), frozenset({'C', 'D'}),
frozenset({'B', 'E'}), frozenset({'B', 'A'}),
frozenset({'C', 'A'})}
如您所見, res
中的項目是frozenset
對象,即它們不依賴於元組中的排序。 因為set
是不可散列的,所以需要frozenset
而不是set
。
一種更有效的單遍解決方案是使用seen
dict來跟蹤到目前為止“看到”給定值的鍵的列表:
pairs = set()
seen = {}
for key, values in d.items():
for value in values:
if value in seen:
for seen_key in seen[value]:
pairs.add(frozenset((key, seen_key)))
seen.setdefault(value, []).append(key)
pairs
將變為:
{frozenset({'D', 'A'}), frozenset({'B', 'E'}), frozenset({'B', 'A'}), frozenset({'C', 'D'}), frozenset({'C', 'A'})}
然后,您可以根據需要輕松地將其轉換為一組按字典順序排序的元組:
{tuple(sorted(p)) for p in pairs}
返回:
{('A', 'C'), ('B', 'E'), ('C', 'D'), ('A', 'D'), ('A', 'B')}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.