一般而言,如果您想在字典列表中查找重复项,您应该按照一种方式对字典进行分类,使得重复项保留在同一组中。为了实现这一目的,您需要基于 dict
项目进行分类。由于对于字典,顺序并不重要,因此您需要使用一个既可散列又不保留容器顺序的容器。最好的选择是使用 frozenset()
。
示例:
In [87]: lst = [{2: 4, 6: 0},{20: 41, 60: 88},{5: 10, 2: 4, 6: 0},{20: 41, 60: 88},{2: 4, 6: 0}]
In [88]: result = defaultdict(list)
In [89]: for i, d in enumerate(lst):
...: result[frozenset(d.items())].append(i)
...:
In [91]: result
Out[91]:
defaultdict(list,
{frozenset({(2, 4), (6, 0)}): [0, 4],
frozenset({(20, 41), (60, 88)}): [1, 3],
frozenset({(2, 4), (5, 10), (6, 0)}): [2]})
在这种情况下,您可以根据 'un'
键对字典进行分类,然后根据 id
选择所需的项:
>>> from collections import defaultdict
>>>
>>> d = defaultdict(list)
>>>
>>> for i in a:
... d[i['un']].append(i)
...
>>> d
defaultdict(<type 'list'>, {'a': [{'un': 'a', 'id': 'cd'}, {'un': 'a', 'id': 'cm'}], 'c': [{'un': 'c', 'id': 'vd'}, {'un': 'c', 'id': 'a'}, {'un': 'c', 'id': 'vd'}], 'b': [{'un': 'b', 'id': 'cd'}, {'un': 'b', 'id': 'cd'}]})
>>>
>>> keeps = {'a': 'cm', 'b':'cd', 'c':'vd'}
>>>
>>> [i for key, val in d.items() for i in val if i['id']==keeps[key]]
[{'un': 'a', 'id': 'cm'}, {'un': 'c', 'id': 'vd'}, {'un': 'c', 'id': 'vd'}, {'un': 'b', 'id': 'cd'}, {'un': 'b', 'id': 'cd'}]
>>>
在最后一行(嵌套的列表推导式)中,我们首先循环遍历聚合字典的项,然后遍历值,并保留那些在值之后的项目或条件中的项,即
i['id']==keeps[key]
表示我们将保留具有指定值的
keeps
字典中
id
的项。
您可以将列表推导式分解为以下内容:
final_list = []
for key, val in d.items():
for i in val:
if i['id']==keeps[key]:
final_list.append(i)
请注意,由于列表推导式的迭代是在C中执行的,因此它比常规的Python循环更快,并且是Pythonic的方式。但是,如果性能对您不重要,则可以使用常规方法。
['un']
值的重复? - Aarondict
是 Python 内置的用于创建字典的命令,因此您可能要避免将其用作变量名。 - Chris Mueller