Je souhaite supprimer les objets de dictionnaire dupliqués d'une liste de dictionnaires. Je ne veux pas de l'élément dict qui a le même élément «plaque» avec un autre élément dict dans la liste. Je ne le veux qu'une seule fois.
[
{
'plate': "01",
'confidence' : "80"
},
{
'plate': "02",
'confidence' : "91"
},
{
'plate': "02",
'confidence' : "91"
},
]
Ma sortie devrait être comme ceci:
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))
Ceci est mon code, mais je ne reçois pas le résultat exact.
datalist = [
{
'plate': "01",
'confidence' : "80"
},
{
'plate': "02",
'confidence' : "91"
},
]
Cela me donne le résultat:
datalist = [
{
'plate': "01",
'confidence' : "80"
},
{
'plate': "01",
'confidence' : "60"
},
{
'plate': "02",
'confidence' : "91"
},
{
'plate': "02",
'confidence' : "91"
},
]
qui n'est pas attendu, quel est le problème avec mon code .
7 Réponses :
Si un élément des groupes de doublons est acceptable, vous pouvez faire:
[{'plate': '02', 'confidence': '91'}, {'plate': '01', 'confidence': '80'}]
Sortie
result = list({d['plate']: d for d in reversed(datalist)}.values())
L'idée est de créer un dictionnaire où les clés sont des valeurs de plaque et les valeurs sont les dictionnaires eux-mêmes. Si vous souhaitez conserver les premières entrées en double, utilisez inversé : p>
[{'plate': '02', 'confidence': '91'}, {'plate': '01', 'confidence': '60'}]
Sortie
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)
Cela produit un résultat erroné car les dernières entrées dupliquées sont conservées, pas la première.
@timgeb OP n'a pas clairement spécifié qu'ils voulaient la première entrée - seulement qu'ils ne voulaient pas d'entrées en double.
@MatthiasFischer OP a spécifié la sortie souhaitée.
vous pouvez toujours le faire en remplaçant datalist par datalist [:: - 1] ou reverse (datalist) pour quelque chose de plus efficace en boucle.
@timgeb Pour le premier exemple, mais nous ne savons pas s'ils veulent toujours la première entrée. Vous avez probablement raison et je suis pédant, mais ce n'est pas explicitement indiqué. :)
@timgeb a mis à jour la réponse!
@DanielMesejo Merci beaucoup pour la réponse rapide. Cela fonctionne comme je le voulais. La seule pièce d'énigme restante était de préserver l'ordre, et pour cela j'ai ajouté une autre ligne de code, results_sorted = sorted (results, key = lambda k: k ['epoch_time']) Heureusement j'ai eu le "Epoch Time" dans la liste, qui et d'autres quelques touches que j'ai supprimées pour la clarté de la question. Et j'ai trié les dictionnaires par "heure d'époque" et ça va maintenant.
En supposant que vous ne souhaitiez conserver que le premier dict dupliqué trouvé, vous pouvez utiliser 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'}]
Si vous voulez à la place les derniers doublons, itérer simplement dans reverse () .
Vous pouvez utiliser la recette En interne, cette solution utilise unique_everseen , également disponible dans les more_itertools a >: from more_itertools import unique_everseen
from operator import itemgetter
datalist = list(unique_everseen(datalist, key=itemgetter('plate')))
set pour garder une trace des plaques vues, ne produisant que des dictionnaires avec de nouvelles valeurs de plaque. Par conséquent, l'ordre est conservé et seule la première instance d'une assiette donnée est conservée.
Bonne utilisation de itemgetter () ici.
Bonne réponse pour les non-initiés, comme moi. Bien que je préfère les pandas comme méthode plus simple.
Si vous êtes un utilisateur pandas , vous pouvez envisager
>>> pd.DataFrame(datalist).drop_duplicates('plate', keep='last').to_dict(orient='records')
[{'confidence': '60', 'plate': '01'}, {'confidence': '91', 'plate': '02'}]
Si vous souhaitez conserver les derniers doublons vus, passez keep = 'last' .
>>> 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'}]
Vous pouvez utiliser un groupe par:
[{'plate': '01', 'confidence': '80'}, {'plate': '02', 'confidence': '91'}]
Résultats:
list(map(lambda x: next(x[1]), groupby(sorted(datalist, key=lambda d: d['plate']), lambda d: d['plate'])))
cela nécessite le tri de la liste initiale.
vous pouvez également utiliser pandas
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' ou 'last' vous aidera dans quelle entrée conserver en sortie
Euh, je ne savais pas que vous pouviez passer 'record' au lieu de 'records' . Cela ne semble pas documenté. +1 pour connaissance obscure :)
Mise à jour: il semble que vous puissiez passer 'r' , 're' , ..., 'records' , 'recordsasdf' , ...
: D Merci @timgeb. Nous pouvons utiliser tout ce qui commence par «r». Je viens de vérifier le code source. github.com/pandas- dev / pandas / blob / v0.23.4 / pandas / core /…
Bonne vieille boucle for verbeuse, puis compréhension de la liste:
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'}]
En relation, pas en double exact car ici, nous ne voulons considérer qu'une seule clé lors de l'examen des doublons: Supprimer le dict en double dans la liste en Python
vous pouvez également utiliser pandas import pandas comme pd; df = pd.DataFrame (données = liste de données); df.drop_duplicates (subset = ['plate'], keep = 'first', inplace = True); sortie = df.to_dict (orient = 'enregistrement')