簡體   English   中英

比較字典中的元組列表

[英]Comparing list of tuples within dictionary

我一直在努力解決這個問題...我有一個簡化的數據集,例如:
dict = {'A': [('a', 1, 1), ('b', 2, 2), ('c', 3, 3)], 'B': [('b', 2, 2), ('a', 1, 1)], 'C': [('d', 4, 4)], 'D': [('c', 3, 3), ('e', 5, 5)]}
其中的值表示元組列表。

我需要為字典中的每個值查找,是否在另一個值的列表元素中找到列表元素? 如果是,則應從字典中刪除鍵值對。 例如,在[['a',1,1),('b',2,2),('中找到[['b',2,2),('a',1,1)] c',3、3)],因此應刪除“ B”的鍵值對。 最終的字典應如下所示:

dict = {'A': [('a', 1, 1), ('b', 2, 2), ('c', 3, 3)], 'C': [('d', 4, 4)], 'D': [('c', 3, 3), ('e', 5, 5)]}

我已經搜索了論壇,但沒有找到解決該問題的方法...非常感謝您的幫助! 謝謝!

編輯:

該詞典不包含重復值,因為我之前已根據另一組條件通過映射到另一本詞典將其刪除。 但是,如果解決方案也可以擴展到重復項,例如將所有重復項中的1個保留下來,則可能對其他人有用。
PS:感謝您的所有答復!

您可以使用集合檢查彼此之間是否包含一個值( set.issubset(otherset) )。 下面的代碼演示了如何輕松實現這一目標。 對於每個值,都會檢查其他每個值是否包含在內。 可以明確地對其進行優化。

# input data
d = {'A': [('a', 1, 1), ('b', 2, 2), ('c', 3, 3)], 'B': [('b', 2, 2), ('a', 1, 1)], 'C': [('d', 4, 4)]}

# convert each value to a set
ds = { k: frozenset(v) for k,v in d.items() }
# filter out contained values
keys = [ k1 for k1,v1 in ds.items() if [k2 for k2,v2 in ds.items() if v1.issubset(v2)] == [k1] ]
# map filtered keys to original dict
df = dict(zip(keys, map(d.get, keys)))
# df = {'A': [('a', 1, 1), ('b', 2, 2), ('c', 3, 3)], 'C': [('d', 4, 4)]}

說明

當計算每對(k1,v1)keys ,將執行以下操作。 檢查所有其他對(k2,v2) (包括(k1,v1) )是否存在v1.issubset(v2) 對於滿足該條件的所有對,密鑰( k2 )被記錄並存儲在列表中。 如果沒有其他值包含我們的給定值v1此列表將僅包含k1 ,因為issubset關系是自反的( v.issubset(v)始終為True )。 因此,當返回的列表正好是[k1] ,我們就可以了。 如果列表包含的值多於k1 ,則v1包含在其他值中,並且必須進行過濾。

值重復

沒有為映射中的重復值定義問題。 我的解決方案跟蹤原始鍵,因此對於重復的值,兩對都將被丟棄。 您還可以在此處引入自定義行為,例如僅對所有重復項使用“最小”鍵保留該對。

其他解決方案保留所有對,因此返回的映射仍然包含重復值。

修改后的keys版本可以處理上述情況:

keys = [ k1 for k1,v1 in ds.items()
            if not any(v1 < v2 for v2 in ds.values())
               and k1 == min(k2 for k2,v2 in ds.items() if v1 == v2) ]

您可以將值轉換為凍結集的集合,然后過濾掉重復項,最后選擇值在集合中的字典項:

d = {
    'A': [('a', 1, 1), ('b', 2, 2), ('c', 3, 3)],
    'B': [('b', 2, 2), ('a', 1, 1)],
    'C': [('d', 4, 4)]
}

sets = {frozenset(v) for v in d.values()}
sets = {s for s in sets if not any(s < s2 for s2 in sets)}
res = {k: v for k, v in d.items() if set(v) in sets} # {'A': [('a', 1, 1), ('b', 2, 2), ('c', 3, 3)], 'C': [('d', 4, 4)]}

使用setcombinations

from itertools import combinations

d = {'A': [('a', 1, 1), ('b', 2, 2), ('c', 3, 3)], 'B': [('b', 2, 2), ('a', 1, 1)], 'C': [('d', 4, 4)]}

xs = set()

for (ai, av), (bi, bv) in combinations(d.items(), 2):
    if set(av) <= set(bv): xs.add(ai)
    if set(bv) <= set(av): xs.add(bi)

for x in xs: del d[x]
print d
# {'A': [('a', 1, 1), ('b', 2, 2), ('c', 3, 3)], 'C': [('d', 4, 4)]}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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