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

这个列表:[{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}]


当前回答

有时老式的循环仍然有用。这段代码比jcollado的稍长,但非常容易阅读:

a = [{'a': 123}, {'b': 123}, {'a': 123}]
b = []
for i in range(len(a)):
    if a[i] not in a[i+1:]:
        b.append(a[i])

其他回答

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

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}]

如果您操作的是嵌套字典,例如反序列化的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]

不是很短,但很容易读:

list_of_data = [{'a': 123}, {'b': 123}, {'a': 123}]

list_of_data_uniq = []
for data in list_of_data:
    if data not in list_of_data_uniq:
        list_of_data_uniq.append(data)

现在,列表list_of_data_uniq将拥有唯一的字典。

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

>>> 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)。

试试这个:

[dict(t) for t in {tuple(d.items()) for d in l}]

策略是将字典列表转换为元组列表,其中元组包含字典的项。由于元组可以散列,您可以使用set(此处使用set理解,旧的python替代方法是set(tuple(d.s items()) for d in l))删除重复项,然后使用dict从元组重新创建字典。

地点:

L是原始列表 D是列表中的一个字典 T是从字典中创建的元组之一

编辑:如果你想保持顺序,上面的一行代码将不起作用,因为set不会这样做。然而,用几行代码,你也可以做到这一点:

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

seen = set()
new_l = []
for d in l:
    t = tuple(d.items())
    if t not in seen:
        seen.add(t)
        new_l.append(d)

print new_l

示例输出:

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

注意:正如@alexis指出的那样,两个具有相同键和值的字典可能不会产生相同的元组。如果他们经历了不同的添加/删除键历史记录,就可能发生这种情况。如果这是您的问题,那么考虑按照他的建议对d.s items()进行排序。