2

我试图在 Python 中做一个相当简单的操作,但我很难理解为什么我会在标题中收到错误消息moment_list.remove(moment_list[i]) 。我的代码是:

for i in range(0,len(moment_list_sum)): 
    if moment_list_sum[i]==nMoments:
        moment_list.remove(moment_list[i])
        LHS.remove(LHS[i])
    else:
        pass

如您所见,我正在尝试从两个列表中删除moment_list满足LHSif 循环中条件的索引,而另一个列表中的相同索引等于 nMoments。

进入循环 nMoments 是一个等于 3 的 int,列表是:

LHS                [y_0, y_1, yx1, yx2, yx3, yx4, yx5, yx6, yx7]
moment_list        [[1, 0], [0, 1], [0, 2], [1, 1], [2, 0], [0, 3], [1, 2], [2, 1], [3, 0]]
moment_list_sum    [1, 1, 2, 2, 2, 3, 3, 3, 3]

它们的长度都相同,所以我不知道为什么会出现列表索引错误,非常感谢任何帮助!

4

2 回答 2

1

举个例子:

[1、2、3、4、5]

这个列表的长度是5,range(5) = [0,1,2,3,4]

假设在第 1 次迭代中,您删除了一个元素。现在列表的长度为 4,但您仍将遍历第 5 个索引。在那种情况下,第五个元素不再存在。

您可能遇到的另一个问题是元素跳过,这一次不会产生错误。以同样的例子,你删除 1。第二个元素是 2,被移动到 0 索引,当你迭代到第二个索引列表1实际上是 3,完全跳过检查之前的第二个元素 (2)。

在大多数计算语言中解决这个问题的常用方法是向后迭代列表。

但是在python中,最好的方法实际上是先搜索然后再删除操作。首先搜索所有需要删除的元素,将它们存储在一个集合中,然后将它们从列表中一个一个删除。

另一种方法是使用itertools过滤器创建一个过滤列表:

import itertools

ifilter(lambda x: x==nMoments, moment_list_sum)
于 2013-06-10T10:13:41.223 回答
0

正如其他人所提到的,您正在修改列表的长度,所以当您到达最后时,您正在查看的索引不再存在。

相反,您应该建立由您需要的元素组成的替换列表。这可能会起作用:

LHS, moment_list = zip(*[
    (LHS_elem, moment_list_elem)
    for i, (LHS_elem, moment_list_elem) in enumerate(zip(LHS, moment_list))
    if moment_list_sum[i] != nMoments])

这样做是将两个目标列表连接在一起,然后使用 enumerate 遍历它们以给出一个索引,您可以使用该索引在第三个列表中查找,然后在最后解压缩它们。

于 2013-06-10T10:15:29.683 回答