您正在更改列表的长度,同时在一个范围内循环到列表的起始长度;从列表中删除一项,最后一个索引不再有效。
移动,因为项目从当前索引的列表中删除,列表索引的其余部分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
现在i
针对每个循环迭代的新i
长度进行测试,并且我们仅在没有元素被删除时才增加。请注意,循环限制为长度减 1,因为您要测试test[i + 1]
每次迭代。
请注意,我使用del test[i]
; 无需再次扫描列表搜索要删除的值;如果值在列表中出现多次但仅应删除后面的实例,这也可能导致细微的错误;例如['aac', 'foo', 'aac', 'aad']
应该导致['aac', 'foo', 'aad']
, not ['foo', 'aac', 'aad']
, 这就是test.remove(test[i])
会导致的结果。
演示:
>>> 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']
这两种方法都只需要一个循环通过输入列表。