Getting the difference between 2 lists that contain dictionaries
本问题已经有最佳答案,请猛点这里访问。
1 2 | list1 = [{'key1': 'item1'}, {'key2': 'item2'}] list2 = [{'key1': 'item1'}, {'key2': 'item2'}, {'key3': 'item3'}] |
这两个清单有什么区别吗?
基本上,我需要一种可伸缩的方法来获得包含字典的两个列表之间的差异。所以我想比较一下这些列表,得到一个
您可以使用列表理解:
1 2 3 4 | list1 = [{'key1': 'item1'}, {'key2': 'item2'}] list2 = [{'key1': 'item1'}, {'key2': 'item2'}, {'key3': 'item3'}] print([x for x in list2 if x not in list1]) |
这将给EDOCX1[0]
您可以使用
1 2 3 4 5 6 7 8 9 10 11 | 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) |
输出:
1 | {'key3': 'item3'} |
1 2 | 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] |
您也可以尝试使用
1 2 3 4 5 6 7 8 9 10 11 | 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'}] |
另一种方法是使用
1 2 3 4 5 6 7 | 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'}] |
您可以通知字典如何散列自身,然后可以使用集合
1 2 3 4 5 6 | import json class HashableDict(dict): def __hash__(self): # convert the dictionary to something hashable - in this case a str return hash(json.dumps(self)) |
然后你可以做
1 2 3 | hashable_list1 = map(HashableDict, list1) hashable_list2 = map(HashableDict, list2) set(hashable_list2).difference(hashable_list1) |
如果你想要所有的区别,那么所有不在这两个列表中的项目都需要:
1 | set(hashable_list2).symmetric_difference(hashable_list1) |
注意:这不适用于所有字典(例如,包含
因为字典不可散列,所以散列不是一种简单的方法,但是因为每个字典都有一个键和一个VAL,所以我们可以构建自己的键!所以你可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
输出:
1 | [{'key3': 'item3'}] |
不是因为这个解决方案具有持续的查找能力,所以它比简单地遍历第一个列表更具可伸缩性。