簡體   English   中英

在Python中,計算字典中的唯一鍵/值對

[英]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.

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