web-dev-qa-db-fra.com

Python: Comment supprimer tous les éléments en double d'une liste

Comment utiliser python pour vérifier une liste et supprimer tous les doublons? Je ne veux pas avoir à spécifier quel est le doublon, je veux que le code détermine s'il y en a et le supprime si c'est le cas, en ne conservant qu'une seule instance de chacun. Cela doit également fonctionner s'il y a plusieurs doublons dans une liste. 

Par exemple, dans mon code ci-dessous, la liste lseparatedOrbList contient 12 éléments: un est répété six fois, un cinq fois et il n'y en a qu'un exemple. Je veux qu'il modifie la liste afin qu'il n'y ait que trois éléments - un de chaque, et dans le même ordre où ils sont apparus avant. J'ai essayé ceci:

for i in lseparatedOrbList:
   for j in lseparatedOrblist:
        if lseparatedOrbList[i] == lseparatedOrbList[j]:
            lseparatedOrbList.remove(lseparatedOrbList[j])

Mais je reçois l'erreur:

Traceback (most recent call last):
  File "qchemOutputSearch.py", line 123, in <module>
    for j in lseparatedOrblist:
NameError: name 'lseparatedOrblist' is not defined

J'imagine que c'est parce que j'essaie de faire une boucle dans lseparatedOrbList pendant que je la fais, mais je ne peux pas penser à une autre façon de le faire.

32
laplacian

Créez simplement une nouvelle liste à remplir. Si l'élément de votre liste ne figure pas encore dans la nouvelle liste, saisissez-le, sinon passez à l'élément suivant de votre liste d'origine.

for i in mylist:
  if i not in newlist:
    newlist.append(i)

Je pense que c'est la syntaxe correcte, mais mon python est un peu fragile, j'espère que vous aurez au moins l'idée.

67
Jonathon Vandezande

Utilisez set():

woduplicates = set(lseparatedOrblist)

Retourne un ensemble sans doublons. Si vous avez besoin d'une liste pour une raison quelconque:

woduplicates = list(set(lseperatedOrblist))
68
Jacob

Vous pouvez faire ça comme ça:

x = list(set(x))

Exemple: si vous faites quelque chose comme ça:

x = [1,2,3,4,5,6,7,8,9,10,2,1,6,31,20]
x = list(set(x))
x

vous verrez le résultat suivant:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 31]

Il n’ya qu’une chose à laquelle vous devriez penser: la liste résultante ne sera pas ordonnée comme la liste originale (elle perdra la commande dans le processus).

29
Tadeck

Cela devrait être plus rapide et préserver la commande d'origine:

seen = {}
new_list = [seen.setdefault(x, x) for x in my_list if x not in seen]

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

new_list = list(set(my_list))
17
Paolo Moretti

Cela devrait le faire pour vous:

new_list = list(set(old_list))

set supprimera automatiquement les doublons. list le remettra à une liste.

6
Manny D

Non, c'est simplement une faute de frappe, la "liste" à la fin doit être en majuscule. Vous pouvez imbriquer des boucles sur la même variable sans problème (même s’il existe rarement une bonne raison de le faire).

Cependant, il y a d'autres problèmes avec le code. Pour commencer, vous parcourez des listes, donc i et j seront des éléments et non des index. En outre, vous ne pouvez pas modifier une collection en effectuant une itération dessus (eh bien, vous "pouvez" dans la mesure où elle fonctionne, mais la folie réside de cette façon - par exemple, vous éviterez probablement les éléments). Et puis il y a le problème de complexité, votre code est O (n ^ 2). Convertissez la liste en une variable set et inversement en une variable list (simple, mais mélange les éléments restants de la liste) ou effectuez les opérations suivantes:

seen = set()
new_x = []
for x in xs:
    if x in seen:
        continue
    seen.add(x)
    new_xs.append(x)

Les deux solutions exigent que les articles soient lavables. Si ce n'est pas possible, vous devrez probablement conserver votre approche actuelle sans les problèmes mentionnés.

6
user395760

C'est parce qu'il vous manque une lettre majuscule, en fait.

Consacré volontairement:

for i in lseparatedOrbList:   # capital 'L'
for j in lseparatedOrblist:   # lowercase 'l'

Bien que le moyen le plus efficace de le faire serait d'insérer le contenu dans une variable set.

Si le maintien de l'ordre de la liste compte (c'est-à-dire qu'il doit être "stable"), consultez les réponses sur cette question

4
Daniel DiPaolo

Le moyen le plus simple consiste à utiliserset ()function:

new_list = list(set(your_list))
4
Nurul Akter Towhid

pour les listes insolubles. Il est plus rapide car il ne s'agit pas des entrées déjà cochées.

def purge_dublicates(X):
    unique_X = []
    for i, row in enumerate(X):
        if row not in X[i + 1:]:
            unique_X.append(row)
    return unique_X
3

Utiliser ensemble

return list(set(result))

Utilisez dict

return dict.fromkeys(result).keys()
2
Simon

La façon moderne de le faire qui maintient l'ordre est la suivante:

>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(lseparatedOrbList))

tel que discuté par Raymond Hettinger (python core dev) dans cette réponse . En python 3.5 et supérieur, c'est aussi le moyen le plus rapide - voir la réponse liée pour plus de détails. Cependant, les clés doivent être hashable (comme c'est le cas dans votre liste, je pense)

0
Mr_and_Mrs_D