2016-07-24 49 views
0

我試圖從列表中刪除重複項。我試圖用下面的代碼來做到這一點。Python 3:IndexError:列表索引超出範圍

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

但我正在逐漸

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

請幫助。

+0

您的一些代碼是否丟失?什麼是'j'?無論如何,我認爲問題在於你正在縮短最後一步。當'i'達到它的最大值時,列表不再那麼長,所以你有一個索引錯誤。 – smarx

+0

什麼是X_length和j? – kaitian521

+0

什麼是'X_length'?什麼是'j'?什麼是X.pop([j])'應該是? –

回答

2

當您開始從列表中刪除項目時,它的大小會發生變化。因此,i個指標可能不再某些清除後存在:

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

更簡單的方法來刪除重複的項目是到您的列表轉換爲set,它只能包含獨特的項目。如果您必須將其作爲列表,則可以將其轉換回列表:list(set(X))。但是,這裏的訂單不會保留。


如果要刪除連續的重複,可以考慮使用新的陣列來存儲 重複項目:

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

需要注意的是我們的必然範圍爲len(x) - 1,否則,我們將超過數組邊界使用x[i+1]

+0

輸入列表是什麼id是'['a','b','c','d','e','f','a','b','a','a']' ?輸出應該是'['a','b','c','d','e','f','a','b','a']'對嗎? – SilentMonk

+0

@SilentMonk是的,只要你把最後一個值添加到新列表中。 –

0

一般不建議在迭代序列時對序列進行變異,因爲序列會不斷變化。這裏有一些其他的方法:

考慮:

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

如果你只從列表中刪除重複項(和順序無關緊要)感興趣的話,可以使用一組:

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

如果你想維持秩序,並在列表中刪除重複隨時隨地,您可以在同時,中心提供全方位製作一個新的列表:

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

如果你想刪除連續重複,考慮@ smarx的答案。

0

在您列表的最後一次迭代中,j的值將設置爲i + 1,在這種情況下長度將爲8。然後嘗試訪問X[j],但j已超出列表的末尾。

相反,只需將列表轉換爲一組:

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

,除非你需要維持秩序,在這種情況下,你需要從其他地方尋找一個ordered set

2

@ Rushy的回答非常好,可能我會推薦。

這就是說,如果要刪除連續的重複你想要做就地(通過修改列表,而不是創建第二個),一個常用的方法是在列表中向後工作方式:

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

通過啓動在列表的末尾和向後移動,就避免了因爲你已經縮短了其運行關閉列表的末尾的問題。

E.g.如果你開始 'AABC' 和向前移動,你將使用索引0,1,2,和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. 

倒退,你會使用索引3,2,1和0 :

3 
    | 
aabc 

    2 
    | 
aabc 

1 
| 
aabc 

(Found a duplicate so remove that element.) 

0 
| 
abc <-- No problem here! 
相關問題