繁体   English   中英

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

[英]I am trying to remove items from a list based upon items from another list (inside a loop). error: list index out of range

这是我的代码:

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”是我要从中删除“ 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

我了解此错误的含义,但我不明白为什么在此发生此错误。 我使用两个列表的长度进行循环。 这是怎么了?

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

尝试以下方法:

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

此列表理解将使oc中不在remlist的项保持remlist

由于您在运行时从oc中删除了一个元素,这就是为什么它将给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]]

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

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

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

问题是,在第二个示例中,您事先告诉循环要遍历2个项目(因为列表的长度为2)。 但是,如果找到并删除一个项目,列表将变小,并且将无法循环您预先设置的整个范围。 我已成为长度为1的列表,因此您无法访问第二项。

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

复制到新列表

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

直接从清单中删除

在这里,您可以使用remove。

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;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM