196 votes

Supprimer les dictées en double dans une liste en Python

J'ai une liste de dicts, et je voudrais enlever les dicts avec des paires de clés et de valeurs identiques.

Pour cette liste : [{'a': 123}, {'b': 123}, {'a': 123}]

J'aimerais rendre ça : [{'a': 123}, {'b': 123}]

Un autre exemple :

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

J'aimerais rendre ça : [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}]

0 votes

Pouvez-vous nous en dire plus sur le problème réel que vous essayez de résoudre ? Cela semble être un problème étrange à avoir.

2 votes

Je combine quelques listes de dicts et il y a des doublons. J'ai donc besoin de supprimer ces doublons.

0 votes

J'ai trouvé une solution dans stackoverflow.com/questions/480214/ dans une réponse sans l'utilisation de set()

15voto

jpp Points 83462

Si vous utilisez Pandas dans votre flux de travail, une option consiste à fournir une liste de dictionnaires directement à la fonction pd.DataFrame le constructeur. Utilisez ensuite drop_duplicates y to_dict pour obtenir le résultat souhaité.

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

12voto

thefourtheye Points 56958

Si vous voulez préserver l'ordre, vous pouvez faire ce qui suit

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

Si l'ordre n'a pas d'importance, alors vous pouvez faire

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

5voto

Highstaker Points 126

Pas une réponse universelle mais si votre liste est trié par une certaine clé, comme ceci :

l=[{'a': {'b': 31}, 't': 1},
   {'a': {'b': 31}, 't': 1},
 {'a': {'b': 145}, 't': 2},
 {'a': {'b': 25231}, 't': 2},
 {'a': {'b': 25231}, 't': 2}, 
 {'a': {'b': 25231}, 't': 2}, 
 {'a': {'b': 112}, 't': 3}]

alors la solution est aussi simple que :

import itertools
result = [a[0] for a in itertools.groupby(l)]

Résultat :

[{'a': {'b': 31}, 't': 1},
{'a': {'b': 145}, 't': 2},
{'a': {'b': 25231}, 't': 2},
{'a': {'b': 112}, 't': 3}]

Fonctionne avec des dictionnaires imbriqués et préserve (évidemment) l'ordre.

1voto

Matimus Points 118

Vous pouvez utiliser un ensemble, mais vous devez transformer les dicts en un type hachable.

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)

Unique est maintenant égal à

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

Pour récupérer les dicts :

[dict(x) for x in unique]

1voto

Johnny.X Points 21

La méthode la plus simple consiste à convertir chaque élément de la liste en chaîne de caractères, puisque le dictionnaire n'est pas hachable. Vous pouvez ensuite utiliser set pour supprimer les doublons.

list_org = [{'a': 123}, {'b': 123}, {'a': 123}]
list_org_updated = [ str(item) for item in list_org]
print(list_org_updated)
["{'a': 123}", "{'b': 123}", "{'a': 123}"]
unique_set = set(list_org_updated)
print(unique_set)
{"{'b': 123}", "{'a': 123}"}

Vous pouvez utiliser l'ensemble, mais si vous voulez une liste, ajoutez ce qui suit :

import ast
unique_list = [ast.literal_eval(item) for item in unique_set]
print(unique_list)
[{'b': 123}, {'a': 123}]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X