dxbjfu0 2019-06-20
Python的for
可以遍历一个List,但是在遍历的过程中删除元素常常会得到意想不到的结果甚至程序出现异常,例如:
lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6] for item in lst: if item == 0: lst.remove(item) print lst
输出: [1, 1, 2, 8, 3, 2, 5, 0, 2, 6]
这段代码的本意是想删除列表中元素为 0 的项,但实际跑起来并不是那个结果。
再看下面这个例子,利用索引来遍历删除列表中的元素:
for item in range(len(lst)): if lst[item] == 0: del lst[item] print lst
输出: IndexError: list index out of range
这时候就报错了,抛出了数组下标越界的异常。原因是用for
发起任何形式的遍历时,它的遍历顺序都是从最初就确定的,而在遍历中删除了元素会导致当前索引的变化,这样一是会导致漏删元素,二是会导致遍历超过链表的长度。
所以遍历一个List时要删除其中的部分元素就需要其他的解决方案。
方法一:可以使用filter
过滤返回新的List
lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6] lst = filter(lambda x: x != 0, lst) print lst
这样可以安全删除列表中值为 0 的元素了,filter
包括两个参数,分别是function
和list
,filter
把传入的函数依次作用于每个元素,然后根据返回值是True
还是False
来决定是保留还是丢弃该元素。
方法二:列表解析
lst = [x for x in lst if x != 0] print lst
方法三:或者遍历拷贝的List,操作原始的List
for item in lst[:]: if item == 0: lst.remove(item) print lst
方法四:用while
循环来搞定,每次循环都先会判断 0 是否在列表中
while 0 in lst: lst.remove(0) print lst
方法五:倒序循环遍历
for item in range(len(lst) - 1, -1, -1): if lst[item] == 0: del lst[item] print lst
倒序是最geek的解决办法,但是倒序的代码可读性差,推荐用filter
,这样写出来的代码更Pythonic。