[英]In Python, count unique key/value pairs in a dictionary
我有一本用值列表制成的字典。 這些值中的一些也是鍵或字典中其他鍵/值對中的值。 我只想計算一下字典中有多少對這些唯一對。
例如 dict = {'dog':['milo','otis','laurel','hardy'],'cat':['bob','joe'],'milo':['otis','laurel','hardy','dog'],'bob':['cat','joe'],'hardy':['dog']}
我需要計算字典中沒有與另一個共享鍵/值的鍵/值對的數量。 例如,上面應僅計為2,與狗和貓有關的那些。 即使milo對於dog而言是唯一的,dog也位於鍵/值對“ hardy”中,因此應將它們一起計算(即,僅1)。 (請參閱下面的評論)我試圖通過用“鍵B”替換另一個鍵(鍵B)的值中存在的鍵(鍵A)來解決此問題,但是沒有成功,因為我無法正確指定鍵B。
for keys, values in dict.iteritems():
for key,value in dict.iteriterms():
if key in values:
dict[keys] = dict.pop(key)
有沒有更簡單的方法? 提前致謝...
如果我正確理解問題,那么您的字典就是圖的鄰接圖,並且您正在嘗試查找連接的組件集。 常規算法(使用深度或廣度優先搜索)可能無法正常工作,因為您的圖形不是無向的(例如,您的邊緣從"bob"
和"cat"
到"joe"
,但沒有一條從"joe"
)。
相反,我建議使用不相交的集合數據結構 。 使用字典來構建值到父母的映射並不難。 這是我為上一個問題編寫的實現:
class DisjointSet:
def __init__(self):
self.parent = {}
self.rank = {}
def find(self, element):
if element not in self.parent: # leader elements are not in `parent` dict
return element
leader = self.find(self.parent[element]) # search recursively
self.parent[element] = leader # compress path by saving leader as parent
return leader
def union(self, leader1, leader2):
rank1 = self.rank.get(leader1,0)
rank2 = self.rank.get(leader2,0)
if rank1 > rank2: # union by rank
self.parent[leader2] = leader1
elif rank2 > rank1:
self.parent[leader1] = leader2
else: # ranks are equal
self.parent[leader2] = leader1 # favor leader1 arbitrarily
self.rank[leader1] = rank1+1 # increment rank
這是使用它來解決問題的方法:
djs = DisjointSet()
all_values = set()
for key, values in my_dict.items():
all_values.add(key)
all_values.update(values)
for val in values:
l1 = djs.find(key)
l2 = djs.find(val)
if l1 != l2:
djs.union(l1, l2)
roots = {djs.find(x) for x in all_values}
print("The number of disjoint sets is:", len(roots))
該代碼的第一部分做了兩件事。 首先,它構建一個集合,其中包含在圖中任何位置找到的所有唯一節點。 其次,它通過在有邊緣的地方進行並集,將節點組合成不相交的集合。
第二步是從不相交集中構建一組“根”元素。
這是一種可能的解決方案:
values = {'dog':['milo','otis','laurel','hardy'],
'cat':['bob','joe'],
'milo':['otis','laurel','hardy','dog'],
'bob':['cat','joe'],
'hardy':['dog']}
result = []
for x in values.iteritems():
y = set([x[0]] + x[1])
if not any([z for z in result if z.intersection(y)]):
result.append(y)
print len(result)
請注意,您不應調用變量dict
因為您將隱藏內置類型dict
。
您的目標尚不明確,但是您可以修改y
set
的構造以滿足您的需求。
如果我正確理解了您的問題,那么您正在嘗試描述類似圖形的結構,並且正在查看鍵是否出現在值列表中。 由於您只對計數感興趣,因此在遍歷dict時不必擔心將來的值列表,因此這應該可行:
d = {'dog': ['milo','otis','laurel','hardy'],'cat': ['bob','joe'],'milo': 'otis','laurel','hardy','dog'], 'bob': ['cat','joe'], 'hardy': ['dog']}
seen = set()
unique = []
for key, values in d.iteritems():
if key not in seen:
unique.append(key)
seen = seen.union(values)
print(len(unique))
注意, unique
中包含的實際值取決於dict的順序,僅是鍵,而不是值。 如果您實際上正在嘗試某種形式的網絡或圖形分析,建議您使用諸如networkx之類的庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.