IndexError:删除重复项时列出索引超出范围

时间:2014-09-18 03:53:31

标签: python duplicate-removal

此代码有效

  X = ['jennifer', 1, 1, 2, 'apple', 3, 3, 1, 'apple', ['true', 'burps','taste',   'good'], ['true', 'burps', 'taste', 'good'], 3, 'jennifer'] 

for index in reversed(range(len(X))):
  if X.count(X[index]) > 1:
      X.remove(X[index])

给我一​​个没有重复的列表

[2, 1, 'apple', ['true', 'burps', 'taste', 'good'], 3, 'jennifer']

我只是不明白为什么这只有在反向时才有效。为什么以下不是完全相同的事情?

for i in range(0,len(X)):
    if X.count(X[i]) > 1:
        X.remove(X[i])

我收到错误

 if X.count(X[i]) > 1:
 IndexError: list index out of range

无论哪种方式,我从我正在阅读的列表中删除一个元素,那么为什么第一个例子不会超出范围而第二个例子呢?我可以对第二个例子做些什么来使它工作吗?

3 个答案:

答案 0 :(得分:1)

在迭代中更改列表并不是一个好主意,如:

for i in range(0,len(X)):
if X.count(X[i]) > 1:
    X.remove(X[i])

一个选项是创建一个包含您要删除的列表的列表,然后再次迭代复制不在此列表中的人。

另一种选择是使用不允许重复的set object

答案 1 :(得分:1)

您在迭代时修改列表,因此每次删除某些内容时都会减少其len,并且在迭代结束时,您的索引将超出范围。通过倒退,你不会遇到这个问题。

答案 2 :(得分:1)

不,你的第二个例子不起作用。反转版本工作的原因是,在最坏的情况下,您只访问列表中的“最后”元素。

假设X有5个元素并且都是重复的,所以你要删除所有元素,直到剩下一个元素。首先,len(X)为5,因此您的for循环将循环4 3 2 1 0。每次删除1个元素时,列表会缩小1.因此,您可以访问的最大索引从4开始,然后缩小为3210,这正是您访问列表的顺序,因此您不会有IndexError。

索引值的表格,以及每个步骤中可从X访问的最大索引:

index  Max. index of X
4      4
3      3
2      2
1      1
0      0

如果您尝试每轮删除多个元素(例如,1步中的所有重复项),您可能会再次看到IndexError。