如何从词典列表中删除重复的词典对象

时间:2019-01-04 12:54:41

标签: python list dictionary

我想从词典列表中删除重复的词典对象。 我不希望dict元素与列表中的另一个dict元素具有相同的“ plate”元素。我只想要一次。

datalist = [

{
    'plate': "01",
    'confidence' : "80"
},

{
    'plate': "01",
    'confidence' : "60"
},

{
    'plate': "02",
    'confidence' : "91"
},

{
    'plate': "02",
    'confidence' : "91"
},
]

我的输出应该是这样的:

datalist = [

{
    'plate': "01",
    'confidence' : "80"
},

{
    'plate': "02",
    'confidence' : "91"
},
]

这是我的代码,但是我没有得到确切的结果。

def filter(datalist):
    previous = ""
    for data in datalist:
        current  = data['plate']
        if current is previous:
            datalist.remove(data)
        previous = current 

    return datalist

datalist = [

    {
        'plate': "01",
        'confidence' : "80"
    },

    {
        'plate': "01",
        'confidence' : "60"
    },

    {
        'plate': "02",
        'confidence' : "91"
    },

    {
        'plate': "02",
        'confidence' : "91"
    },
]


print (filter(datalist))

这给了我输出:

[

    {
        'plate': "01",
        'confidence' : "80"
    },

    {
        'plate': "02",
        'confidence' : "91"
    },

    {
        'plate': "02",
        'confidence' : "91"
    },
]

这是不期望的,我的代码出了什么问题。

7 个答案:

答案 0 :(得分:6)

如果重复组中的任何元素均可接受,则可以执行以下操作:

datalist = [
    {'plate': "01", 'confidence': "80"},
    {'plate': "01", 'confidence': "60"},
    {'plate': "02", 'confidence': "91"},
    {'plate': "02", 'confidence': "91"},
]

result = list({ d['plate'] : d for d in datalist }.values())
print(result)

输出

[{'plate': '02', 'confidence': '91'}, {'plate': '01', 'confidence': '60'}]

这个想法是创建一个字典,其中的键是plate的值,而值是字典本身。如果要保留第一个重复的条目,请使用reversed

result = list({d['plate']: d for d in reversed(datalist)}.values())

输出

[{'plate': '02', 'confidence': '91'}, {'plate': '01', 'confidence': '80'}]

答案 1 :(得分:3)

假设您只想保留找到的第一个重复的字典,则可以使用setdefault()

datalist = [
    {"plate": "01", "confidence": "80"},
    {"plate": "01", "confidence": "60"},
    {"plate": "02", "confidence": "91"},
    {"plate": "02", "confidence": "91"},
]

result = {}
for d in datalist:
    result.setdefault(d["plate"], d)

print(list(result.values()))
# [{'plate': '01', 'confidence': '80'}, {'plate': '02', 'confidence': '91'}]

如果您想要最后一个重复项,只需在reverse()中进行迭代。

答案 2 :(得分:3)

您可以使用unique_everseen recipe,也可以在第三方more_itertools中使用:

from more_itertools import unique_everseen
from operator import itemgetter    

datalist = list(unique_everseen(datalist, key=itemgetter('plate')))

在内部,此解决方案使用set来跟踪可见的印版,仅生成具有新印版值的字典。因此,将保持顺序,并且仅保留任何给定板的第一个实例。

答案 3 :(得分:3)

如果您是pandas用户,可以考虑

>>> import pandas as pd
>>> datalist = [{'plate': "01", 'confidence': "80"}, {'plate': "01", 'confidence': "60"}, {'plate': "02", 'confidence': "91"}, {'plate': "02", 'confidence': "91"}]
>>> pd.DataFrame(datalist).drop_duplicates('plate').to_dict(orient='records')                                                                               
[{'confidence': '80', 'plate': '01'}, {'confidence': '91', 'plate': '02'}]

如果要保留最后一次看到的重复项,请传递keep='last'

>>> pd.DataFrame(datalist).drop_duplicates('plate', keep='last').to_dict(orient='records')
[{'confidence': '60', 'plate': '01'}, {'confidence': '91', 'plate': '02'}]

答案 4 :(得分:3)

您也可以使用熊猫

import pandas as pd
df = pd.DataFrame(data = datalist)
df.drop_duplicates(subset = ['plate'],keep='first',inplace=True)
output = df.to_dict(orient='record')

keep ='first'或'last'将有助于将哪个条目保留在输出中

答案 5 :(得分:2)

您可以使用一个分组方式:

list(map(lambda x: next(x[1]), groupby(sorted(datalist, key=lambda d: d['plate']), lambda d: d['plate'])))

结果:

[{'plate': '01', 'confidence': '80'}, {'plate': '02', 'confidence': '91'}]

答案 6 :(得分:2)

良好的旧式for循环,然后进行列表理解:

tmp=[]
for dct in datalist:
  if not any(e[0] == dct["plate"] for e in tmp):
    tmp.append((dct["plate"], dct["confidence"]))


[ {"plate": plate, "confidence": confidence} for plate, confidence in tmp ]
#=> [{'plate': '01', 'confidence': '80'}, {'plate': '02', 'confidence': '91'}]