[英]Python Difference between 2 lists
I found many examples but not one with duplicate items.我发现了很多例子,但没有一个有重复项目。
I have 2 list of dict:我有 2 个字典列表:
d1 = [{"id": 1, "value": 2}, {"id": 1, "value": 2}]
d2 = [{"id": 1, "value": 2}, {"id": 4, "value": 4}]
What I want to achieve is:我想要实现的是:
d1-d2
[{"id": 1, "value": 2}]
d2-d1
[{"id": 4, "value": 4}]
diff(d1, d2)
[{"id": 1, "value": 2}, {"id": 4, "value": 4}]
You can do something like this but it's not that pretty:你可以做这样的事情,但它不是那么漂亮:
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
Then you can use sub(d1, d2) + sub(d2, d1)
to get diff(d1, d2)
.然后你可以使用
sub(d1, d2) + sub(d2, d1)
来获得diff(d1, d2)
。
Assuming your values, not just the keys, in each dictionary are hashable, you can make frozenset
s of each dict
s .items()
, collect them into a collections.Counter
, and perform an xor-like operation on the Counter
s to get the disparate counts.假设您的值,而不仅仅是键,在每个字典中都是可散列的,您可以制作每个
dict
s frozenset
.items()
的 frozenset ,将它们收集到collections.Counter
中,并对Counter
s 执行类似 xor 的操作以获得不同的计数。 Then you just flatten out the Counter
again, and convert the frozenset
s back to dict
s:然后你只需再次展平
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()))
The simpler operation of computing d1 - d2
or d2 - d1
is left as an exercise;计算
d1 - d2
或d2 - d1
的更简单操作留作练习; the key in all cases is converting your list
of dict
s to Counter
s of frozenset
s of the dict
's .items()
, performing the operation you care about with -
, then converting back to a list
of dict
s.在所有情况下,关键是将您的
dict
list
转换为dict
的.items()
的frozenset
的Counter
,使用-
执行您关心的操作,然后转换回dict
list
。
This should be fairly efficient (roughly O(n)
on combined input sizes);这应该是相当有效的(在组合输入大小上大约为
O(n)
); improving on it would require a lot more custom code that's frankly not worth the bother.改进它需要更多的自定义代码,坦率地说,这不值得费心。
Not elegant, but this seems to work:不优雅,但这似乎有效:
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.