list1 = [{'key1': 'item1'}, {'key2': 'item2'}]
list2 = [{'key1': 'item1'}, {'key2': 'item2'}, {'key3': 'item3'}]
有没有办法得到这两个列表之间的差异?
基本上,我需要一种可扩展的方法来获取2个包含字典的列表之间的差异。因此,我尝试比较这些列表,并只获得{'key3': 'item3'}
答案 0 :(得分:14)
您可以使用列表理解:
list1 = [{'key1': 'item1'}, {'key2': 'item2'}]
list2 = [{'key1': 'item1'}, {'key2': 'item2'}, {'key3': 'item3'}]
print([x for x in list2 if x not in list1])
哪个会给[{'key3': 'item3'}]
答案 1 :(得分:2)
您可以将set()
与以下示例结合使用:
def get_diff(elm1, elm2):
a = set((m, n) for k in elm1 for m, n in k.items())
b = set((m, n) for k in elm2 for m, n in k.items())
if len(b) > len(a):
return dict(b - a)
return dict(a - b)
list1 = [{'key1': 'item1'}, {'key2': 'item2'}]
list2 = [{'key1': 'item1'}, {'key2': 'item2'}, {'key3': 'item3'}]
get_diff(list1, list2)
输出:
{'key3': 'item3'}
答案 2 :(得分:1)
in_list1_not_in_list2 = [i for i in list1 if i not in list2]
in_list2_not_in_list1 = [i for i in list2 if i not in list1]
答案 3 :(得分:0)
由于字典不可哈希,因此没有一种简单的哈希方法,但是由于每个词典只有一个键和一个val,因此我们可以构建自己的键!因此,您可以执行以下操作:
list1_set = set()
for dictionary in list1:
key = dictionary.keys()[0]
vals = dictionary.values()[0]
custom_key = '{}|{}'.format(key,vals)
list1_set.add(custom_key)
differences = []
for dictionary in list2:
key = dictionary.keys()[0]
vals = dictionary.values()[0]
custom_key = '{}|{}'.format(key,vals)
if custom_key not in list1_set:
differences.append(dictionary)
print differences
输出:
[{'key3': 'item3'}]
由于具有恒定的查找能力,因此该解决方案的可伸缩性要比简单地遍历第一个列表大得多。
答案 4 :(得分:0)
您可以通知字典如何对其自身进行散列,然后可以使用sets
import json
class HashableDict(dict):
def __hash__(self):
# convert the dictionary to something hashable - in this case a str
return hash(json.dumps(self))
那你就可以做
hashable_list1 = map(HashableDict, list1)
hashable_list2 = map(HashableDict, list2)
set(hashable_list2).difference(hashable_list1)
difference
为您提供了list2中不在list1中的元素。
如果您希望所有这些都与众不同,那么所有不在两个列表中的项都请执行:
set(hashable_list2).symmetric_difference(hashable_list1)
请注意,这不适用于所有词典(例如,包含json.dumps
无法使用的对象的词典),除非您也使用自定义JSONEncoder
答案 5 :(得分:0)
您还可以尝试使用set.symmetric_difference()
来获得这两种方式之间的差异:
list1 = [{'key1': 'item1'}, {'key2': 'item2'}]
list2 = [{'key1': 'item1'}, {'key2': 'item2'}, {'key3': 'item3'}]
set1 = set(tuple(x.items())[0] for x in list1)
set2 = set(tuple(x.items())[0] for x in list2)
print([dict(list(set1.symmetric_difference(set2)))])
# [{'key3': 'item3'}]
print([dict(list(set2.symmetric_difference(set1)))])
# [{'key3': 'item3'}]
另一种方法是使用itertools.filterfalse()
:
from itertools import filterfalse
diff1 = list(filterfalse(lambda d: d in list2, list1))
diff2 = list(filterfalse(lambda d: d in list1, list2))
print(diff1 + diff2)
# [{'key3': 'item3'}]