Python 3:IndexError:列表索引超出范围

Python 3:IndexError:列表索引超出范围

问题描述:

我试图从列表中删除重复项。我试图用下面的代码来做到这一点。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])'应该是? –

当您开始从列表中删除项目时,它的大小会发生变化。因此,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是的,只要你把最后一个值添加到新列表中。 –

一般不建议在迭代序列时对序列进行变异,因为序列会不断变化。这里有一些其他的方法:

考虑:

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的答案。

在您列表的最后一次迭代中,j的值将设置为i + 1,在这种情况下长度将为8。然后尝试访问X[j],但j已超出列表的末尾。

相反,只需将列表转换为一组:

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

,除非你需要维持秩序,在这种情况下,你需要从其他地方寻找一个ordered set

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