[英]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)]}
使用set
和combinations
:
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.