我试图根据另一个列表中的项目(在循环内)从列表中删除项目。错误:列表索引超出范围

时间:2014-05-26 12:28:12

标签: python list

这是我的代码:

print('oc before remove',oc)
print('remlist before remove', remlist)

for i in range(len(remlist)):
    for j in range(len(oc)):
        if ( (remlist[i][0] == oc[j][0]) and (remlist[i][1] == oc[j][1]) ):
            del oc[j]

print('oc after remove', oc)

'oc'是de list,我想从中删除也出现在'remlist'中的项目。我的prints输出以下内容:

('oc before remove', [[0, 0, 0]])
('remlist before remove', [[0, 0, 0]])
('oc after remove', [])
('oc before remove', [[1, 0, 1], [0, 1, 1]])
('remlist before remove', [[0, 0, 0], [1, 0, 1]])

此处发生错误。

所以第一次成功,但第二次出现以下错误:

IndexError: list index out of range

我理解这个错误的含义,但是我不明白为什么会出现这个错误。我使用两个列表的长度循环。这里出了什么问题?

5 个答案:

答案 0 :(得分:2)

您的问题是您在迭代期间更改了列表的大小。这显然是一个问题,因为删除一些项后,您的j循环变量将超出新的(删除后)列表长度的范围。它第一次起作用,因为列表只包含1个元素。

请改为尝试:

oc = [item for item in oc if item not in remlist]

此列表理解将保留oc内不属于remlist的项目。

答案 1 :(得分:2)

由于你在运行时删除了一个元素,这就是为什么它会给IndexError: list index out of range,所以oc [1]元素将会丢失。

我使用while loop处理案例。

>>>oc =  [[1, 0, 1], [0, 1, 1]]
>>>remlist = [[0, 0, 0], [1, 0, 1]]
for i in range(len(remlist)):
    j = 0
    while j <len(oc):
        if ( (remlist[i][0] == oc[j][0]) and (remlist[i][1] == oc[j][1]) ):
            del oc[j]
            j = j-1

        j = j+1

结果:

>>>oc
[[0, 1, 1]]
>>>remlist
[[0, 0, 0], [1, 0, 1]]

答案 2 :(得分:1)

len(oc)仅在您进入循环时进行一次评估,但在一次迭代后删除一个元素,因此更改了列表的长度。在下一次迭代中,您尝试访问oc[1][0],但此时oc只有1个元素,因此抛出异常。

另请注意,您只比较每个元素中的前2个元素(在您的示例中,每个元素包含3个元素)。

答案 3 :(得分:1)

问题是您在循环中删除列表中的项目。 对于长度为1的列表,这不会产生任何问题,但是长于1的任何问题都会产生问题,因为列表在循环时会变短。

事情是,在你的第二个例子中,事先你告诉循环超过2个项目(因为你的列表长度为2)。但是,如果您找到并删除某个项目,该列表会变小,并且无法循环您预先设置的整个范围。我已成为长度为1的列表,因此您无法访问第二项。

答案 4 :(得分:1)

有两种方法: 1)创建一个新列表并在其中复制oc而不是remlist中的元素, 2)直接从oc中删除remlist中的元素(在oc很大的情况下)。

复制到新列表

res = []
for e in oc:
    if not e in remlist:
        res.append(e)

直接从列表中删除

在这里,你可以使用删除。

for e in remlist:
    for i in xrange(oc.count(e)): oc.remove(e)

备注

我不知道为什么你只比较子列表的第一个和第二个元素:

if ((remlist[i][0] == oc[j][0]) and (remlist[i][1] == oc[j][1])): ...

写下来就足够了:

if (remlist[i] == oc[j]): ...

如果您确定自己在做什么,请至少使用:

if (remlist[i][0:2] == oc[j][0:2]): ...

它更pythonic;)