这是我的代码:
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
我理解这个错误的含义,但是我不明白为什么会出现这个错误。我使用两个列表的长度循环。这里出了什么问题?
答案 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;)