web-dev-qa-db-fra.com

Ajouter uniquement des valeurs uniques à une liste en python

J'essaie d'apprendre le python. Voici la partie pertinente de l'exercice: 

Pour chaque mot, vérifiez si le mot est déjà dans une liste. Si la Word n'est pas dans la liste, ajoutez-le à la liste.

Voici ce que j'ai 

fhand = open('romeo.txt')
output = []

for line in fhand:
    words = line.split()
    for Word in words:
        if Word is not output:
            output.append(Word)

print sorted(output)

Voici ce que je reçois. 

['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'and', 'and', 'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'is', 'is', 'kill', 'light', 'moon', 'pale', 'sick', 'soft', 'Sun', 'Sun', 'the', 'the', 'the', 'through', 'what', 'window', 'with', 'yonder']

Notez la duplication (et, est, Sun, etc.). 

Comment puis-je obtenir que des valeurs uniques?

14
Tim Elhajj

Pour éliminer les doublons d'une liste, vous pouvez gérer une liste auxiliaire et effectuer une vérification.

myList = ['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'and', 'and', 
     'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'is', 'is', 'kill', 'light', 
     'moon', 'pale', 'sick', 'soft', 'Sun', 'Sun', 'the', 'the', 'the', 
     'through', 'what', 'window', 'with', 'yonder']

auxiliaryList = []
for Word in myList:
    if Word not in auxiliaryList:
        auxiliaryList.append(Word)

sortie:

['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'breaks', 'east', 
  'envious', 'fair', 'grief', 'is', 'kill', 'light', 'moon', 'pale', 'sick',
  'soft', 'Sun', 'the', 'through', 'what', 'window', 'with', 'yonder']

C'est très simple à comprendre et le code est explicite. Cependant, la simplicité du code se fait au détriment de l'efficacité du code car des balayages linéaires sur une liste de plus en plus longue font qu'un algorithme linéaire se dégrade en quadratique. 


Utilisez set () !, un set est une collection non ordonnée ne contenant aucun élément dupliqué. 
Les utilisations de base comprennent les tests d’adhésion et l’élimination des entrées en double.

auxiliaryList = list(set(myList))

sortie:

['and', 'envious', 'already', 'fair', 'is', 'through', 'pale', 'yonder', 
 'what', 'Sun', 'Who', 'But', 'moon', 'window', 'sick', 'east', 'breaks', 
 'grief', 'with', 'light', 'It', 'Arise', 'kill', 'the', 'soft', 'Juliet']
30
Tony Tannous

Au lieu d'opérateur is not, vous devez utiliser l'opérateur not in pour vérifier si l'élément est dans la liste:

if Word not in output:

BTW, en utilisant set est beaucoup efficace (Voir Complexité temporelle ):

with open('romeo.txt') as fhand:
    output = set()
    for line in fhand:
        words = line.split()
        output.update(words)

UPDATE La set ne conserve pas l'ordre d'origine. Pour préserver l'ordre, utilisez l'ensemble en tant que structure de données auxiliaire:

output = []
seen = set()
with open('romeo.txt') as fhand:
    for line in fhand:
        words = line.split()
        for Word in words:
            if Word not in seen:  # faster than `Word not in output`
                seen.add(Word)
                output.append(Word)
9
falsetru

Voici un "one-liner" qui utilise cette implémentation pour supprimer les doublons tout en préservant l'ordre:

def unique(seq):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if not (x in seen or seen_add(x))]

output = unique([Word for line in fhand for Word in line.split()])

La dernière ligne aplatit fhand en une liste de mots, puis appelle unique() dans la liste résultante.

1
Mateen Ulhaq

Une méthode consiste à voir si cela est dans la liste avant d'ajouter, ce que fait la réponse de Tony. Si vous voulez supprimer les doublons après la liste a été créée, vous pouvez utiliser set() pour convertir la liste existante en un ensemble de valeurs uniques, puis utiliser list() pour la convertir en liste encore. Tout en une seule ligne:

list(set(output))

Si vous souhaitez effectuer un tri alphabétique, ajoutez simplement un _sorted() à ce qui précède. Voici le résultat:

['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'kill', 'light', 'moon', 'pale', 'sick', 'soft', 'Sun', 'the', 'through', 'what', 'window', 'with', 'yonder']

1
Advait S