2016-07-24 15 views
0

Ich versuche, Duplikate aus einer Liste zu entfernen. Ich versuche das mit dem unteren Code zu tun.Python 3: IndexError: Listenindex außerhalb des Bereichs

>>> X 
['a', 'b', 'c', 'd', 'e', 'f', 'a', 'b'] 
>>> for i in range(X_length) : 
... j=i+1 
... if X[i] == X[j] : 
... X.pop([j]) 

Aber ich bin immer

Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
IndexError: list index out of range 

Bitte helfen.

+0

Ist ein Teil Ihres Codes nicht vorhanden? Was ist "j"? Auf jeden Fall nehme ich an, dass das Problem darin besteht, dass Sie das letzte Mal kürzen, während Sie gehen. Zu dem Zeitpunkt, an dem "i" seinen Maximalwert erreicht, ist die Liste nicht mehr so ​​lang, so dass Sie einen Indexfehler haben. – smarx

+0

Was ist X_length und j? – kaitian521

+0

Was ist 'X_length'? Was ist 'j'? Was soll X.pop ([j]) sein? –

Antwort

2

Wenn Sie beginnen, Elemente aus einer Liste zu entfernen, ändert sich ihre Größe. So gibt es die i ten Index möglicherweise nicht mehr nach bestimmten Umzügen:

>>> x = ['a', 'b', 'c', 'd', 'e'] 
>>> x[4] 
'e' 
>>> x.pop() 
'e' 
>>> x[4] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: list index out of range 

Ein einfacherer Weg, um doppelte Einträge zu entfernen, ist die Liste zu einem set zu konvertieren, die nur eindeutigen Elemente enthalten können. Wenn Sie es als Liste haben müssen, können Sie es zurück in eine Liste konvertieren: list(set(X)). Die Reihenfolge ist hier jedoch nicht erhalten.


Wenn Sie aufeinander folgende Duplikate zu entfernen, sollten Sie eine neue Array Elemente zu speichern, die nicht Duplikate:

unique_x = [] 
for i in range(len(x) - 1): 
    if x[i] != x[i+1]: 
     unique_x.append(x[i]) 
unique_x.append(x[-1]) 

Beachten Sie, dass unsere gebundenen Bereich len(x) - 1 denn sonst ist, würden wir das nicht überschreiten Array-Grenzen bei Verwendung von x[i+1].

+0

Was ist die Eingangsliste? ['A', 'b', 'c', 'd', 'e', ​​'f', 'a', 'b', 'a', 'a'] ' ? Die Ausgabe sollte lauten: ['a', 'b', 'c', 'd', 'e', ​​'f', 'a', 'b', 'a'] 'richtig? – SilentMonk

+0

@SilentMonk Ja, solange Sie den letzten Wert an die neue Liste anhängen. –

0

Es wird generell nicht empfohlen, eine Sequenz während der Iteration zu mutieren, da sich die Sequenz ständig ändert. Hier sind einige andere Ansätze:

Gegeben:

X = ['a', 'b', 'c', 'd', 'e', 'f', 'a', 'b'] 

Wenn Sie daran interessiert sind nur in Duplikate aus einer Liste zu entfernen (und um nicht egal), können Sie einen Satz verwenden:

list(set(X)) 
['a', 'c', 'b', 'e', 'd', 'f'] 

Wenn Sie Auftrag erhalten wollen und Duplikate überall in der Liste zu entfernen, können Sie es erate während eine neue Liste machen:

X_new = [] 
for i in X: 
    if i not in X_new: 
     X_new.append(i) 

X_new 
# Out: ['a', 'b', 'c', 'd', 'e', 'f'] 

Wenn Sie in Folge Duplikate entfernen möchten, @ Antwort des Smarx betrachten.

0

In der letzten Iteration Ihrer Liste wird der Wert j auf i + 1 gesetzt, was in diesem Fall die Länge oder 8 ist. Sie versuchen dann, auf X[j] zuzugreifen, aber j ist über das Ende der Liste hinaus.

Stattdessen wandeln Sie einfach die Liste auf einen Satz:

>>> set(X) 
{'e', 'f', 'd', 'c', 'a', 'b'} 

es sei denn, Sie zu erhalten, um brauchen, in diesem Fall werden Sie an anderer Stelle für eine ordered set aussehen müssen.

2

@ Rushys Antwort ist großartig und wahrscheinlich, was ich empfehlen würde.

Das heißt, wenn Sie aufeinander folgende Duplikate entfernen möchten, und Sie wollen es an Ort und Stelle tun (durch die Änderung der Liste, anstatt eine zweite zu schaffen), ist eine übliche Technik, den Weg rückwärts durch die Liste zu arbeiten :

def remove_consecutive_duplicates(lst): 
    for i in range(len(lst) - 1, 1, -1): 
     if lst[i] == lst[i-1]: 
      lst.pop(i) 

x = ['a', 'b', 'b', 'c', 'd', 'd', 'd', 'e', 'f', 'f'] 
remove_consecutive_duplicates(x) 
print(x) # ['a', 'b', 'c', 'd', 'e', 'f'] 

am Ende der Liste und rückwärts bewegen Mit dem Start, Sie das Problem der wegzulaufen das Ende der Liste vermeiden, weil Sie es verkürzt haben.

z. wenn Sie mit 'aabc' und bewegen nach vorne starten, werden Sie die Indizes 0, 1 verwenden, 2 und 3.

0 
| 
aabc 

(Found a duplicate, so remove that element.) 

1 
| 
abc 

    2 
    | 
abc 

    3 
    | 
abc <-- Error! You ran off the end of the list. 

rückwärts gehend, werden Sie die Indizes 3, 2, 1, verwenden und 0 :

3 
    | 
aabc 

    2 
    | 
aabc 

1 
| 
aabc 

(Found a duplicate so remove that element.) 

0 
| 
abc <-- No problem here! 
Verwandte Themen