我有两个字典列表,希望找到它们之间的区别(即第一个列表中存在但第二个列表中不存在的内容,以及第二个列表中存在但第一个列表中不存在的内容)。
问题在于这是一个字典列表。
a = [{'a': '1'}, {'c': '2'}]
b = [{'a': '1'}, {'b': '2'}]
set(a) - set(b)
结果
TypeError: unhashable type: 'dict'
期望的结果:
{'c': '2'}
我该怎么做才能实现这个目标?
我有两个字典列表,希望找到它们之间的区别(即第一个列表中存在但第二个列表中不存在的内容,以及第二个列表中存在但第一个列表中不存在的内容)。
问题在于这是一个字典列表。
a = [{'a': '1'}, {'c': '2'}]
b = [{'a': '1'}, {'b': '2'}]
set(a) - set(b)
结果
TypeError: unhashable type: 'dict'
期望的结果:
{'c': '2'}
我该怎么做才能实现这个目标?
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'}]
>>> 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'}]
+
运算符来连接a_minis_b
和b_minus_a
到sym_diff
中,而不是使用itertools.chain
吗? - Iron Fistitertools.chain()
,在使用结果列表之前,您不必在内存中构建它。对于“大”列表尤其重要。为了更加一致,我应该在这里使用生成器而不是列表推导式:a_minus_b = (item for item in a if item not in b)
。但是,在该示例代码中,这将更加棘手,因为生成器在使用它们时会消耗项目。 - Sylvain Lerouxlambda
和filter一起使用: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)
for uniq in diff:
print uniq