簡體   English   中英

從字典中返回一組具有共同值的鍵對

[英]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")}

使用itertools.combinations

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM