当前位置: 首页 > 面试题库 >

删除列表项时发生意外的IndexError [重复]

锺离韬
2023-03-14
问题内容

这个问题已经在这里有了答案

如何在迭代时从列表中删除项目? (26个答案)

4年前关闭。

我是Python的初学者。我以前学过其他语言,例如C ++(入门)和JQuery。但是我发现python中的循环非常混乱。

好吧,我想取得一个简单的结果。该程序将循环浏览单词列表,然后将与列表中 两个字母匹配的单词与下一个单词删除:

test = ['aac', 'aad', 'aac', 'asd', 'msc']
for i in range(len(test)):
    if test[i][0:2] == test[i+1][0:2]:
        test.remove(test[i])

# This should output only ['aac', 'asd', 'msc']
print test

上面的代码应该删除'aac',并'aad'从列表中。但实际上,这引发了一个IndexError。此外,我无法达到预期的效果。你能解释一下吗?


问题答案:

您要更改列表的长度,同时循环使用一个达到列表起始长度的范围;从列表中删除一个项目,最后一个索引不再有效。

移动,因为从当前索引的列表中删除了项目,所以列表的其余索引 转移了 ;索引处的i + 1内容现在位于索引处,i并且循环索引不再有用。

最后但并非最不重要的一点是,您一直循环到的最后一个索引test,但随后尝试test[i + 1]仍然访问;即使您没有从列表中删除元素,该索引也不存在。

您可以使用while循环来实现您想做的事情:

test = ['aac', 'aad', 'aac', 'asd', 'msc']
i = 0
while i < len(test) - 1:
    if test[i][:2] == test[i+1][:2]:
        del test[i]
        continue
    i += 1

现在i,在每次循环迭代中针对 新的 长度进行测试,并且只有i在未删除任何元素的情况下,我们才递增。请注意,循环限于长度 减去1,
因为您要为test[i + 1]每次迭代进行测试。

注意我用del test[i]; 无需浏览列表即可 再次 搜索要删除的值;如果值在列表中多次出现,但仅应删除 以后的
实例,这也可能导致细微的错误;例如,['aac', 'foo', 'aac', 'aad']应导致['aac', 'foo', 'aad']
而不是 ['foo', 'aac', 'aad'],这test.remove(test[i])将导致结果。

演示:

>>> test = ['aac', 'aad', 'aac', 'asd', 'msc']
>>> i = 0
>>> while i < len(test) - 1:
...     if test[i][:2] == test[i+1][:2]:
...         del test[i]
...         continue
...     i += 1
... 
>>> test
['aac', 'asd', 'msc']

您可以使用列表理解来避免列表缩小的问题:

>>> [t for i, t in enumerate(test) if i == len(test) - 1 or t[:2] != test[i + 1][:2]]
['aac', 'asd', 'msc']

两种方法都只需要在输入列表中循环一次。



 类似资料:
  • 我有一个自定义列表类的应用程序。尝试使用customer参数执行foreach函数时,会发生以下情况: 重要!我不能修改主代码 主要内容: XList类: 错误:

  • 问题内容: 编写一个程序来检查列表中是否有重复项,如果删除了重复项,则将其删除,并返回一个包含未重复项/已删除项的新列表。这就是我所拥有的,但老实说我不知道​​该怎么办。 问题答案: 获取唯一项目集合的常用方法是使用。集是不同对象的无序集合。要从任何迭代创建集合,只需将其传递给内置函数即可。如果以后再次需要真实列表,则可以类似地将集合传递给函数。 以下示例应涵盖你尝试做的所有事情: 从示例结果中可

  • 问题内容: 我在Python中有一个列表列表: 我想从中删除重复的元素。如果这是正常列表,而不是我可以使用的列表set。但不幸的是,该列表不可散列,因此无法建立一组列表。只有元组。因此,我可以将所有列表转换为元组,然后使用set并返回列表。但这不是很快。 如何以最有效的方式做到这一点? 上面的结果应为: 我不在乎保留订单。 注意:这个问题很相似,但不是我所需要的。搜索了SO,但没有找到确切的重复项

  • 我试图从列表中删除一个项目,如果它在中位数的四分位数范围之外。

  • 问题内容: 我有两个列表需要合并,第二个列表忽略了第一个列表的重复项。..有点难以解释,所以让我展示一个代码看起来像什么,以及我想要什么的示例。 您会注意到结果具有第一个列表, 包括 其两个“ 2”值,但是second_list也具有附加的2和5值这一事实并未添加到第一个列表中。 通常,对于这样的事情,我会使用集合,但是first_list上的集合会清除它已经具有的重复值。所以我只是想知道什么是实

  • 我下面有一个类,想删除包含同名的重复人,如何使用Java8 Lambda,预计列表包含下面的p1、p3。