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

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


当前回答

如果你不关心规模和疯狂的性能,简单的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

其他回答

可以使用set,但需要将字典转换为可哈希类型。

seq = [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}, {'a': 123, 'b': 1234}]
unique = set()
for d in seq:
    t = tuple(d.iteritems())
    unique.add(t)

唯一的现在等于

set([(('a', 3222), ('b', 1234)), (('a', 123), ('b', 1234))])

要找回字典:

[dict(x) for x in unique]

有很多搜索重复值和键的好例子,下面是我们在列表中过滤整个字典重复数据的方法。如果您的源数据是由EXACT格式的字典组成并寻找重复项,请使用dupKeys =[]。否则设置dupKeys =为您希望没有重复条目的数据的键名,可以是1到n个键。它不优雅,但工作和非常灵活

import binascii

collected_sensor_data = [{"sensor_id":"nw-180","data":"XXXXXXX"},
                         {"sensor_id":"nw-163","data":"ZYZYZYY"},
                         {"sensor_id":"nw-180","data":"XXXXXXX"},
                         {"sensor_id":"nw-97", "data":"QQQQQZZ"}]

dupKeys = ["sensor_id", "data"]

def RemoveDuplicateDictData(collected_sensor_data, dupKeys):

    checkCRCs = []
    final_sensor_data = []
    
    if dupKeys == []:
        for sensor_read in collected_sensor_data:
            ck1 = binascii.crc32(str(sensor_read).encode('utf8'))
            if not ck1 in checkCRCs:
                final_sensor_data.append(sensor_read)
                checkCRCs.append(ck1)
    else:
        for sensor_read in collected_sensor_data:
            tmp = ""
            for k in dupKeys:
                tmp += str(sensor_read[k])

            ck1 = binascii.crc32(tmp.encode('utf8'))
            if not ck1 in checkCRCs:
                final_sensor_data.append(sensor_read)
                checkCRCs.append(ck1)
  
           
    return final_sensor_data    

 final_sensor_data = [{"sensor_id":"nw-180","data":"XXXXXXX"},
                      {"sensor_id":"nw-163","data":"ZYZYZYY"},
                      {"sensor_id":"nw-97", "data":"QQQQQZZ"}]
    

有时老式的循环仍然有用。这段代码比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])

使用自定义键删除重复项:

def remove_duplications(arr, key):
    return list({key(x): x for x in arr}.values())

如果您在工作流中使用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}]