background image
python for 循环 remove 同一个 list
下午在用 python 将 Linux 的 conf 配置文件转化成字典 dict 时遇到了一个奇怪的问题,原
先 conf 配置文件中没有注释行(以#开头的行),后来为了避免这种情况,添加了一个对以
#开头的行删除的操作。 实践结果颠覆了已有的认知,直接上代码示例。
代码片段 1
1
2
3
4
5
6
7
8
9
#!/usr/bin/python
# encoding: utf-8
# -*- coding: utf8 -*-
import
re
list_to_test
=
[
'# '
,
'# conf'
,
'NAME="Ubuntu"'
,
'VERSION="14.04.3 LTS
, Trusty Tahr"'
]
for
member
in
list_to_test:
if
re.search(
'^#+.*'
, member)
is not
None
:
list_to_test.remove(member)
print
list_to_test
结果 1:['# conf', 'NAME="Ubuntu"', 'VERSION="14.04.3 LTS, Trusty Tahr"']
代码片段 2
1
2
3
4
5
6
7
#!/usr/bin/python
# encoding: utf-8
# -*- coding: utf8 -*-
list_to_test
=
[
'# '
,
'# conf'
,
'NAME="Ubuntu"'
,
'VERSION="14.04.3 LTS
, Trusty Tahr"'
]
list_to_test.remove(
'# '
)
list_to_test.remove(
'# conf'
)
print
list_to_test
# 结果 2:['NAME="Ubuntu"', 'VERSION="14.04.3 LTS, Trusty Tahr"']
本以为上述两个代码的结果应该是一样的,结果不一样。
分析:
原因是不能在 for 循环中用 remove 同一个列表(遍历中删除)。当 remove 这个 list 中的
元素时,list 的长度发生了变化,for 循环就会受到影响(这个 python 版本(2.7.x 没有
明显的报错,可能作者并不认为这是一个 issue 或 bug,但给点提示也是好的啊)。
解决办法:
用一个新的列表(list)去代替循环中的 list 或者代替 remove 操作的 list。在创建新的
列表是可以用 cpoy 模块中的 deepcopy 方法也可以用 new_list = old_list[:]的方法,如
下:
1
#!/usr/bin/python