我有一个字典列表,我想删除字典具有相同的键和值对。

这个列表:[{a: 123}, {b: 123}, {a: 123}]

我想返回这个:[{'a': 123}, {'b': 123}]

另一个例子:

这个列表:[{' a ': 123, ' b ': 1234}, {' a ': 3222, ' b ': 1234}, {' a ': 123, ' b ': 1234}]

我想退回这:[{' a ': 123, ' b ': 1234}, {' a ': 3222, ' b ': 1234}]


当前回答

如果你想维护骑士团,那你可以这么做

from collections import OrderedDict
print OrderedDict((frozenset(item.items()),item) for item in data).values()
# [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}]

如果顺序不重要,那么你可以这样做

print {frozenset(item.items()):item for item in data}.values()
# [{'a': 3222, 'b': 1234}, {'a': 123, 'b': 1234}]

其他回答

如果您在工作流中使用Pandas,一种选择是直接向pd提供字典列表。DataFrame构造函数。然后使用drop_duplicate和to_dict方法获得所需的结果。

import pandas as pd

d = [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}, {'a': 123, 'b': 1234}]

d_unique = pd.DataFrame(d).drop_duplicates().to_dict('records')

print(d_unique)

[{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}]

如果您操作的是嵌套字典,例如反序列化的JSON对象,那么其他答案将不起作用。在这种情况下,你可以使用:

import json
set_of_jsons = {json.dumps(d, sort_keys=True) for d in X}
X = [json.loads(t) for t in set_of_jsons]

如果你不关心规模和疯狂的性能,简单的func:

# Filters dicts with the same value in unique_key
# in: [{'k1': 1}, {'k1': 33}, {'k1': 1}]
# out: [{'k1': 1}, {'k1': 33}]
def remove_dup_dicts(list_of_dicts: list, unique_key) -> list:
    unique_values = list()
    unique_dicts = list()
    for obj in list_of_dicts:
        val = obj.get(unique_key)
        if val not in unique_values:
            unique_values.append(val)
            unique_dicts.append(obj)
    return unique_dicts

下面是一个带有双嵌套列表理解的快速单行解决方案(基于@Emmanuel的解决方案)。

它使用每个字典中的单个键(例如,a)作为主键,而不是检查整个字典是否匹配

[i for n, i in enumerate(list_of_dicts) if i.get(primary_key) not in [y.get(primary_key) for y in list_of_dicts[n + 1:]]]

这不是OP要求的,但这是让我来到这个帖子的原因,所以我想我应该发布我最终得到的解决方案

另一个基于列表推导式的一行代码:

>>> d = [{'a': 123}, {'b': 123}, {'a': 123}]
>>> [i for n, i in enumerate(d) if i not in d[n + 1:]]
[{'b': 123}, {'a': 123}]

在这里,因为我们可以使用字典比较,所以我们只保留初始列表中其余部分中不存在的元素(这个概念只能通过索引n访问,因此使用了enumerate)。