python在遍历时删除元素

Posted by Red on April 2, 2020

python萌新来水一篇博客

问题产生

​ 最近干活儿的时候遇到一个有意思的问题,在用python遍历一个list删除一些不符合条件的元素的时候,怎么都删不干净,看了一下发现了问题,这个问题可以简化为:

1
2
3
4
5
6
7
a = [1,2,3,4]
>>> for i in a:
...     if i <= 3:
...         a.remove(i)
...
>>> a
[2, 4]

所以,2为什么没被删掉???2不小于3???

解决

作为一个萌新,仔细想了想,删除1之后,2,3,4应该是向前移动了,但是第一个位置已经被遍历过了,所以遍历的下一个元素就是3,2就被“吃”掉了,显然不能这么遍历删除,参考了文末的链接之后发现基本是两个思路,第一,新建一个list,将我们想要的放进去:

1
2
3
4
5
6
7
8
9
10
>>> def check(x):
...     if x <= 3:
...         return True
...
>>>
>>> a = [1,2,3,4]
>>> b = [x for x in a if not check(x)]
>>> b
[4]
>>>

新建了一个b,遍历a,把符合条件的加入进来,虽然用list comps会加快速度,但是这个方法有一个问题,就是这个方法创建了一个新的list b,在有多个地方引用原来的list a的时候就会出现问题。第二个思路就解决了这个问题,建立一个原list的副本,然后根据副本信息对原list进行操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> a = [1,2,3,4]
>>> def check(x):
...     if x <= 3:
...         return True
...
>>>
>>> a[:] = [x for x in a if not check(x)]
>>> a
[4]
>>>
>>> a = [1,2,3,4]
>>> for i in a[:]:
...     if i <= 3:
...         a.remove(i)
...
>>> a
[4]
>>>

可以看到,a发生了改变,所以就不用怕多处引用的问题了,当然还有用itertools来进行遍历的,有兴趣可以看看。

参考链接 : https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating