"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_item
和 comparable
只是访问同一列表对象的附加名称。
然后循环遍历 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)
我试图编写一段程序来删除列表中的所有重复项,但我得到了 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_item
和 comparable
只是访问同一列表对象的附加名称。
然后循环遍历 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)