如何找出两个字典列表之间的差异?

19

我有两个字典列表,希望找到它们之间的区别(即第一个列表中存在但第二个列表中不存在的内容,以及第二个列表中存在但第一个列表中不存在的内容)。

问题在于这是一个字典列表。

a = [{'a': '1'}, {'c': '2'}]
b = [{'a': '1'}, {'b': '2'}]

set(a) - set(b)

结果

TypeError: unhashable type: 'dict'

期望的结果:

{'c': '2'}

我该怎么做才能实现这个目标?


1
你的字典真的只有单个项目吗?如果是这样,将列表转换为单个字典会更有意义吧? - cmd
不,它们是多个项目(每个列表大约有15个),并且每个列表中会有大约3000到10000个字典。 - Chris
你能检查一下你想要的结果吗?根据你的定义,你正在寻找一个对称差异。 - Sylvain Leroux
3个回答

24
您可以使用in运算符来查看其是否在列表中。
a = [{'a': '1'}, {'c': '2'}]
b = [{'a': '1'}, {'b': '2'}]

>>> {'a':'1'} in a
True
>>> {'a':'1'} in b
True

>>> [i for i in a if i not in b]
[{'c': '2'}]

4
我希望找到它们之间的差异(即第一个列表中存在但第二个列表中不存在的内容,以及第二个列表中存在但第一个列表中不存在的内容)。根据您的定义,您正在寻找对称差集
>>> import itertools

>>> a = [{'a': '1'}, {'c': '2'}]
>>> b = [{'a': '1'}, {'b': '2'}]
>>> intersec = [item for item in a if item in b]
>>> sym_diff = [item for item in itertools.chain(a,b) if item not in intersec]

>>> intersec
[{'a': '1'}]
>>> sym_diff
[{'c': '2'}, {'b': '2'}

另外一种方法(使用你的示例中给出的plain difference):

>>> a_minus_b = [item for item in a if item not in b]
>>> b_minus_a = [item for item in b if item not in a]
>>> sym_diff = list(itertools.chain(a_minus_b,b_minus_a))

>>> a_minus_b
[{'c': '2'}]
>>> b_minus_a
[{'b': '2'}]
>>> sym_diff
[{'c': '2'}, {'b': '2'}]

这在其中一个答案中被引用,但我相信这正是OP想要的...所以+1。一个问题,你不能只使用+运算符来连接a_minis_bb_minus_asym_diff中,而不是使用itertools.chain吗? - Iron Fist
1
@KhalilAmmour-خليلعمور 是的,你可以。但是使用itertools.chain(),在使用结果列表之前,您不必在内存中构建它。对于“大”列表尤其重要。为了更加一致,我应该在这里使用生成器而不是列表推导式:a_minus_b = (item for item in a if item not in b)。但是,在该示例代码中,这将更加棘手,因为生成器在使用它们时会消耗项目。 - Sylvain Leroux
啊哈...我明白了...所以那是为了内存优化,您能给我展示一个生成器的例子吗?也许通过编辑您的答案来展示? - Iron Fist

1
你也可以使用lambdafilter一起使用:
如果你想要每个列表中的不同项:
print filter(lambda x: x not in b,a) + filter(lambda x: x not in a,b)

[{'c': '2'}, {'b': '2'}]

或者只需使用filter(lambda x: x not in b,a)来获取在a中但不在b中的元素。 如果您不想在内存中创建完整的字典列表,则可以使用itertools.ifilter

from itertools import ifilter

diff = ifilter(lambda x: x not in b,a)

然后只需遍历 diff:
for uniq in diff:
   print uniq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接