您正在更改列表的长度,同时循环到列表起始长度的范围;从列表中删除一项,最后一个索引不再有效。
移过来,因为项目已从当前索引处的列表中删除,所以列表索引的其余部分shift;索引是什么i + 1
现在处于索引处i
并且您的循环索引不再有用。
最后但并非最不重要的一点是,您将循环直到最后一个索引test
,但随后尝试访问test[i + 1]
仍然;即使您没有从列表中删除元素,该索引也不存在。
你可以使用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
Now i
是针对new每次循环迭代的长度,我们只增加i
如果没有元素被删除。注意循环的长度是有限制的minus 1因为你想测试test[i + 1]
每次迭代。
请注意,我使用del test[i]
;无需扫描列表来搜索要删除的值again;如果值在列表中多次出现但仅出现,这也可能导致微妙的错误later应删除实例;例如['aac', 'foo', 'aac', 'aad']
应该导致['aac', 'foo', 'aad']
, not ['foo', 'aac', 'aad']
,这是什么test.remove(test[i])
会导致.
Demo:
>>> 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
...
>>> test
['aac', 'asd', 'msc']
您可以使用列表理解来避免列表缩小问题:
>>> [t for i, t in enumerate(test) if i == len(test) - 1 or t[:2] != test[i + 1][:2]]
['aac', 'asd', 'msc']
两种方法都只需要对输入列表进行一次循环。