【问题标题】:"list index out of range" - Python“列表索引超出范围” - Python
【发布时间】:2015-03-21 22:34:07
【问题描述】:

我正在尝试编写一段程序来删除列表中的所有重复项,但我得到了 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)

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

【问题讨论】:

  • 你认为x在这种情况下是什么?此外,将列表分配给另一个名称不会创建副本,只是添加对该列表的另一个引用。
  • 您的相等性测试将始终为真,因此项目将被删除,从而索引将不再有效。
  • 你甚至都不知道python中的for循环...先拿一本教科书。
  • 因此,list_item == comparable始终为真
  • 总体上不太明白这一点。

标签: python list indexing


【解决方案1】:

您的代码没有按照您的想法执行。

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

list_item, comparable = any_list, any_list

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

然后循环遍历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?

【讨论】:

    【解决方案2】:

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

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

    您可能遇到了问题,因为您正在修改(删除)列表,同时对其进行迭代。

    【讨论】:

      【解决方案3】:

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

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

      如果你想保留订单,那么

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

      【讨论】:

        猜你喜欢
        • 2015-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多