获取包含字典的2个列表之间的区别

时间:2018-11-11 00:51:10

标签: python list

list1 = [{'key1': 'item1'}, {'key2': 'item2'}]
list2 = [{'key1': 'item1'}, {'key2': 'item2'}, {'key3': 'item3'}]

有没有办法得到这两个列表之间的差异?

基本上,我需要一种可扩展的方法来获取2个包含字典的列表之间的差异。因此,我尝试比较这些列表,并只获得{'key3': 'item3'}

的回报

6 个答案:

答案 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'}]