使用for循环遍历python列表的同时,如果增加或者删除列表里的元素将会破坏列表的迭代器,产生一些看起来很诡异的现象。
已知一个列表,内容如下
lst = [1, 2, 3, 4, 5, 6, 7, 8]
现在要求你删除列表中的奇数,你当如何处理呢,下面是很多人想当然的一种解决方法
lst = [1, 2, 3, 4, 5, 6, 7, 8]
for i in lst:
if i % 2 == 1:
lst.remove(i)
print(lst)
程序输出结果
[2, 4, 6, 8]
从结果看,程序似乎是正确的,但这只是一个巧合,将列表内容替换为下面的内容
lst = [1, 3, 2, 5, 7, 9]
再次执行程序,得到的结果是
[3, 2, 7]
这究竟是为什么?
for循环的本质是使用迭代器进行遍历,删除迭代器访问过的元素,下一次迭代中,迭代器将向后跳转1个元素。
删除元素1时,迭代器向右跳转1个元素,刚好越过了3,是remove 影响了迭代器的正常使用。
如果在for循环进行迭代时,向列表中增加元素,那么迭代器就会向左跳转1个元素,与删除的情况刚好相反。
想在for循环遍历列表的过程中实现删除操作,可以反向遍历列表
lst = [1, 3, 2, 5, 7, 9]
for i in reversed(lst):
if i % 2 == 1:
lst.remove(i)
print(lst)
第二个解决方法是复制一份列表,遍历这个复制的列表,删除原列表里的元素
import copy
lst = [1, 3, 2, 5, 7, 9]
for i in copy.copy(lst):
if i % 2 == 1:
lst.remove(i)
print(lst)
这样的复制是浅拷贝,因此几乎不会消耗多少内存。
QQ交流群: 211426309