[英]Python Difference between 2 lists
我發現了很多例子,但沒有一個有重復項目。
我有 2 個字典列表:
d1 = [{"id": 1, "value": 2}, {"id": 1, "value": 2}]
d2 = [{"id": 1, "value": 2}, {"id": 4, "value": 4}]
我想要實現的是:
d1-d2
[{"id": 1, "value": 2}]
d2-d1
[{"id": 4, "value": 4}]
diff(d1, d2)
[{"id": 1, "value": 2}, {"id": 4, "value": 4}]
你可以做這樣的事情,但它不是那么漂亮:
def sub(d1, d2):
d2_ = d2.copy()
res = []
for elem in d1:
if elem in d2_:
d2_.remove(elem)
else:
res.append(elem)
return res
然后你可以使用sub(d1, d2) + sub(d2, d1)
來獲得diff(d1, d2)
。
假設您的值,而不僅僅是鍵,在每個字典中都是可散列的,您可以制作每個dict
s frozenset
.items()
的 frozenset ,將它們收集到collections.Counter
中,並對Counter
s 執行類似 xor 的操作以獲得不同的計數。 然后你只需再次展平Counter
,並將frozenset
s 轉換回dict
s:
from collections import Counter
def diff(l1, l2):
c1 = Counter(frozenset(d.items()) for d in l1)
c2 = Counter(frozenset(d.items()) for d in l2)
c1xc2 = (c1 - c2) + (c2 - c1) # Equivalent to c1 ^ c2 if they were sets, but we need counts, and Counter doesn't support ^
# elements() flattens the Counter to iterable of repeated values, map(dict, ...)
# converts frozensets back to dicts
return list(map(dict, c1xc2.elements()))
計算d1 - d2
或d2 - d1
的更簡單操作留作練習; 在所有情況下,關鍵是將您的dict
list
轉換為dict
的.items()
的frozenset
的Counter
,使用-
執行您關心的操作,然后轉換回dict
list
。
這應該是相當有效的(在組合輸入大小上大約為O(n)
); 改進它需要更多的自定義代碼,坦率地說,這不值得費心。
不優雅,但這似乎有效:
def diff(d1, d2):
found = []
to_return = []
for item in d1:
if item in found:
continue
found += [item]
to_return += [item] * (len(list(filter(lambda x : x == item, d1))) - len(list(filter(lambda x : x == item, d2))))
return to_return
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.