删除列表项时出现意外的索引器错误

2024-06-09 15:44:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我是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'和{}。但实际上,这会引起IndexError。而且,我没能达到预期的效果。你能解释一下吗?在


Tags: intest程序语言列表for字母range
3条回答

当您从列表中删除项时,range(len(test))仍然保持相同的值。因此,即使您的test列表只剩下一个项目,循环仍在继续。在

我有两个解决方案:

  1. 将您想要的项目复制到新列表中,因此不要删除它:

    test2 = test[i]
    

    别忘了扭转局面。

  2. 向后循环。像这样:

    ^{pr2}$

    或者,正如martijn所说:

    n = len(test)
    for i in range(n-1, 0, -1):
        if i > 1:
        if test[i][0:2] == test[i-1][0:2]:
            test.remove(test[i])
    

希望有帮助!在

抱歉,我之前的回答很愚蠢

正如其他人所说,当您删除项时,列表会变短,从而导致索引错误。在

与原问题保持一致。如果你想用列表.删除从列表中重复找到的项,然后将它们从列表中删除:

# Set up the variables
test = ['aac', 'aad', 'aac', 'asd', 'msc']
found = []
# Loop Over the range of the lenght of the set
for i in range(len(test)):
    try:
        if test[i].startswith(test[i+1][0:2]):
            found.append(test[i])  # Add the found item to the found list
    except IndexError: # You'll hit this when you do test[i+1]
        pass

# Remove the Items at this point so you don't cause any issues
for item in found:
    test.remove(item)  # If an item has been found remove the first instance

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

编辑:

根据马丁斯的评论,你不需要列出第二个需要删除的项目列表,你可以列出一个不需要删除的项目,如下所示:

^{pr2}$

在循环到列表起始长度的范围内循环时,正在更改列表的长度;从列表中删除一项,最后一个索引将不再有效。在

Moveover,因为在当前索引处从列表中删除了项,所以其余的列表索引现在位于索引i + 1处的索引现在位于索引i,因此循环索引不再有用。在

最后但并非最不重要的是,循环到最后一个索引test,但是仍然尝试访问{};即使没有从列表中删除元素,该索引也不存在。在

您可以使用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])将产生的结果。在

演示:

^{pr2}$

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

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

这两种方法都只需要通过输入列表进行一次循环。在

相关问题 更多 >