"list index out of range" - Python

"list index out of range" - Python

我试图编写一段程序来删除列表中的所有重复项,但我得到了 list index out of range

代码如下:

a_list = [1, 4, 3, 2, 3]

def repeating(any_list):
    list_item, comparable = any_list, any_list
    for x in any_list:
        list_item[x]
        comparable[x]
        if list_item == comparable:
            any_list.remove(x)

    print(any_list)

repeating(a_list)

所以我的问题是,怎么了?

解决问题的最简单方法是将列表转换为集合,然后再转换回列表...

def repeating(any_list):
    print list(set(any_list))

您可能遇到了问题,因为您正在修改(删除)列表,同时遍历它。

您的代码与您认为的不同。

首先,您要在此处创建对同一列表的其他引用:

list_item, comparable = any_list, any_list

list_itemcomparable 只是访问同一列表对象的附加名称。

然后循环遍历 contained in any_list:

for x in any_list:

这首先分配 1,然后 4,然后 3,然后 2,然后 3 再次分配给 x

接下来,使用这些值作为对列表的其他两个引用的索引,但忽略这些表达式的结果:

list_item[x]
comparable[x]

除了测试这些索引是否存在之外,这什么都不做。

下面这行总是正确的:

if list_item == comparable:

因为两个变量引用同一个列表对象。

因为这始终为真,所以始终执行以下行:

any_list.remove(x)

这将从列表中删除第一个 x,使列表 更短 ,同时仍在迭代。这会导致 for 循环 跳过 项目,因为它将指针移动到下一个元素。请参阅 Loop "Forgets" to Remove Some Items 了解原因。

总而言之,列表中有 4 个项目,然后是 3 个项目,因此 list_item[3] 然后失败并抛出异常。

删除重复项的正确方法是使用set object:

def repeating(any_list):
    return list(set(any_list))

因为 set 只能容纳唯一的项目。但是它会改变顺序。如果顺序很重要,您可以使用 collections.OrderedDict() object:

def repeating(any_list):
    return list(OrderedDict.fromkeys(any_list))

set 一样,字典只能保存唯一键,但 OrderedDict 实际上也跟踪插入顺序; dict.fromkeys() 方法为 any_list 中的每个元素赋予 None 值,除非该元素已经存在。将其返回到列表中,以先到先得的顺序为您提供独特的元素:

>>> from collections import OrderedDict
>>> a_list = [1, 4, 3, 2, 3]
>>> list(set(a_list))
[1, 2, 3, 4]
>>> list(OrderedDict.fromkeys(a_list))
[1, 4, 3, 2]

有关更多选项,请参阅 How do you remove duplicates from a list in whilst preserving order?

如果您想删除列表中的重复项但又不关心元素的格式,那么您可以

def removeDuplicate(numlist):
    return list(set(numlist))

如果你想保留顺序那么

def removeDuplicate(numlist):
    return sorted(list(set(numlist)), key=numlist.index)