两个列表之间的Python差异
我发现了很多例子,但没有一个有重复的项目 我有两份清单:两个列表之间的Python差异,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,我发现了很多例子,但没有一个有重复的项目 我有两份清单: d1 = [{"id": 1, "value": 2}, {"id": 1, "value": 2}] d2 = [{"id": 1, "value": 2}, {"id": 4, "value": 4}] 我想要实现的是: d1-d2 [{"id": 1,
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 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
你可以做这样的事情,但它并不漂亮:
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.items()
,将它们收集到,并对计数器
s执行类似异或的操作,以获得不同的计数。然后您只需再次展平计数器
,并将冻结集
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
的简单操作留作练习;在所有情况下,关键是将目录的列表
转换为目录的冻结集的计数器
项()
,用-
执行您关心的操作,然后转换回目录的列表
这应该是相当有效的(在组合输入大小上大致O(n)
);改进它需要更多的自定义代码,这显然不值得费心。这两个列表的结合不是你想要的吗?它看起来没有什么区别(即“第一个列表中的元素,而不是第二个列表中的元素”),至少对于函数“diff”,您的dict总是有相同的键吗?您可以将它们转换为元组,然后将它们放入集合中,并对它们使用所有的集合操作。通过减去d1-d2,我想得到需要删除的项目(它们在列表1中,但不在列表2中)。通过减去d2-d1,我想得到我需要添加的元素(它们在d2中,但不在d1中)。这里有一个优雅的解决方案,使用过滤器,但我不够聪明,发现它非常复杂,可能很难维护代码。是的,上面的答案更好;这里有一个一行的答案,但它并不真正值得找到。我将把它作为另一个例子,以防有人关注。这是一个很好的答案+1。请注意,使用这种方法也可以轻松定义sub
函数。@Moosefeather:Yar。我把它留作练习(毕竟这只是diff
函数的简化)。最好让OP编写,以确保他们首先理解diff
;如果他们不这样做,他们可以在这里的评论中询问后续内容。@ShadowRanger它也应该与tuple
一起工作,而不是frozenset
@ChihebNexus:在现代Python中,插入顺序为dict
s时,如果dict
s都是以相同的顺序构造的,它就会工作。但是如果它们不是,例如,如果d2
被定义为OP的问题中所示的,但是d1
被定义为d1=[{“值”:2,“id”:1},{“值”:2,“id”:1}]
(值
在id
之前定义,OP的反面),元组将中断(由于排序)而frozenset
将继续工作。我不想依靠插入顺序的一致性来保证正确性。它不会给你带来任何好处;对于计数器
@ShadowRanger Good point,这些值仍然需要可散列。我忘了点菜会弄坏柜台。