Suppression des doublons dans les listes

En gros, j'ai besoin d'écrire un programme qui vérifie si une liste a des doublons et si c'est le cas, il les supprime et renvoie une nouvelle liste avec les éléments qui n'ont pas été doublés/supprimés. Voici ce que j'ai, mais pour être honnête, je ne sais pas quoi faire.

def remove_duplicates():
    t = ['a', 'b', 'c', 'd']
    t2 = ['a', 'c', 'd']
    for t in t2:
        t.append(t.remove())
    return t
Solution

L'approche commune pour obtenir une collection unique d'éléments est d'utiliser un [set] (http://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset). Les sets sont des collections non ordonnées d'objets distincts. Pour créer un ensemble à partir de n'importe quel itérable, vous pouvez simplement le passer à la fonction intégrée set(). Si, plus tard, vous avez à nouveau besoin d'une liste réelle, vous pouvez de la même manière passer l'ensemble à la fonction list().

L'exemple suivant devrait couvrir ce que vous essayez de faire :

>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> list(set(t))
[1, 2, 3, 5, 6, 7, 8]
>>> s = [1, 2, 3]
>>> list(set(t) - set(s))
[8, 5, 6, 7]

Comme vous pouvez le voir dans le résultat de l'exemple, l'ordre original n'est pas maintenu. Comme mentionné ci-dessus, les ensembles eux-mêmes sont des collections non ordonnées, donc l'ordre est perdu. Lors de la reconversion d'un ensemble en liste, un ordre arbitraire est créé.

Maintien de l'ordre

Si l'ordre est important pour vous, vous devrez utiliser un mécanisme différent. Une solution très courante est de s'appuyer sur OrderedDict pour conserver l'ordre des clés pendant l'insertion :

>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]

À partir de Python 3.7, le dictionnaire intégré est garanti pour maintenir l'ordre d'insertion également, donc vous pouvez aussi l'utiliser directement si vous êtes sur Python 3.7 ou plus (ou CPython 3.6) :

>>> list(dict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]

Notez que cela entraîne la création d'un dictionnaire d'abord, puis d'une liste à partir de celui-ci. Si vous n'avez pas besoin de préserver l'ordre, il est préférable d'utiliser un ensemble. Consultez cette question pour plus de détails et d'autres moyens de préserver l'ordre lors de la suppression des doublons.


Enfin, notez que les solutions set et OrderedDict/dict nécessitent que vos éléments soient hashables. Cela signifie généralement qu'ils doivent être immuables. Si vous devez traiter des éléments qui ne sont pas hachables (par exemple des objets de type liste), vous devrez utiliser une approche lente dans laquelle vous devrez comparer chaque élément avec chaque autre élément dans une boucle imbriquée.

Commentaires (4)

Il s'agit d'une simple ligne : list(set(source_list)) fera l'affaire.

Un "ensemble" est quelque chose qui ne peut pas avoir de doublons.

Mise à jour : une approche préservant l'ordre est en deux lignes :

from collections import OrderedDict
OrderedDict((x, True) for x in source_list).keys()

Ici, nous utilisons le fait que OrderedDict se souvient de l'ordre d'insertion des clés, et ne le change pas quand une valeur à une clé particulière est mise à jour. Nous insérons True comme valeurs, mais nous pourrions insérer n'importe quoi, les valeurs ne sont simplement pas utilisées. (set fonctionne beaucoup comme un dict avec des valeurs ignorées, aussi).

Commentaires (3)

Si vous ne vous souciez pas de l'ordre, faites simplement ceci :

def remove_duplicates(l):
    return list(set(l))

Un set est garanti de ne pas avoir de doublons.

Commentaires (1)