python for循环remove同一个list过程解析


Posted in Python onAugust 14, 2019

下午在用python将Linux的conf配置文件转化成字典dict时遇到了一个奇怪的问题,原先conf配置文件中没有注释行(以#开头的行),后来为了避免这种情况,添加了一个对以#开头的行删除的操作。 实践结果颠覆了已有的认知,直接上代码示例。

代码片段1

#!/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

#!/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[:]的方法,如下:

#!/usr/bin/python
# encoding: utf-8
# -*- coding: utf8 -*-
import re
from copy import deepcopy

old_list = ['# ', '# conf', 'NAME="Ubuntu"', 'VERSION="14.04.3 LTS, Trusty Tahr"']
new_list = deepcopy(old_list)
for member in new_list:
 if re.search('^#+.*', member) is not None:
  old_list.remove(member)
print old_list

有趣(令人困惑)的是切片也是浅复制,但利用切片也可以实现上述功能,代码如下:

#!/usr/bin/python
# encoding: utf-8
# -*- coding: utf8 -*-
import re
old_list = ['# ', '# conf', 'NAME="Ubuntu"', 'VERSION="14.04.3 LTS, Trusty Tahr"']
new_list = old_list[:]
for member in new_list:
 if re.search('^#+.*', member) is not None:
  old_list.remove(member)
print old_list

上述导致错误发生的例子(在for循环中用remove同一个列表)可以认知为这个操作是修改对象势必影响此对象,要想修改一个对象却不影响此对象引用,则需要对象复制。如果你想修改一个对象,而且想让原始的对象不受影响,那你就需要对象复制。

附加知识点:

关于浅复制(浅拷贝)

对象的浅复制(shallow copy):它虽然复制了对象,但对于对象中的元素,依然使用引用.

(1)、使用切片[:]操作进行拷贝 (注释:切片只复制了对象的顶层,对对象的下一层还是引用,举个例子:[1,2,3,[4,5,6]])

(2)、使用工厂函数(如list/dir/set)等进行拷贝

(3)、copy.copy()

(4)、=(赋值)操作(注释:原文没有,此处是新添加的,根据“对象的赋值实际上是对象的引用”添加)

如果希望复制一个容器对象,以及它里面的所有元素(包含元素的子元素),使用copy.deepcopy这个方法会消耗一些时间和空间。不过,如果你需要完全复制,这是唯一的方法。

注意:

1、对于非容器类型(如数字、字符串、和其他‘原子'类型的对象)没有被拷贝一说。

2、如果元组变量只包含原子类型对象,则不能深copy。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
初步探究Python程序的执行原理
Apr 11 Python
Python pickle模块用法实例分析
May 27 Python
Python使用面向对象方式创建线程实现12306售票系统
Dec 24 Python
5种Python单例模式的实现方式
Jan 14 Python
用Python实现数据的透视表的方法
Nov 16 Python
python实现将汉字保存成文本的方法
Nov 16 Python
Python求一批字符串的最长公共前缀算法示例
Mar 02 Python
Python学习笔记之字符串和字符串方法实例详解
Aug 22 Python
python对Excel按条件进行内容补充(推荐)
Nov 24 Python
pytorch模型预测结果与ndarray互转方式
Jan 15 Python
Python reversed反转序列并生成可迭代对象
Oct 22 Python
Python爬虫爬取ts碎片视频+验证码登录功能
Feb 22 Python
如何用Python来理一理红楼梦里的那些关系
Aug 14 #Python
django之自定义软删除Model的方法
Aug 14 #Python
python实现登录密码重置简易操作代码
Aug 14 #Python
python 定时器每天就执行一次的实现代码
Aug 14 #Python
Django 项目重命名的实现步骤解析
Aug 14 #Python
Django如何实现网站注册用户邮箱验证功能
Aug 14 #Python
python 叠加等边三角形的绘制的实现
Aug 14 #Python
You might like
PHP 中执行系统外部命令
2006/10/09 PHP
PHP 的 __FILE__ 常量
2007/01/15 PHP
MySQL GBK→UTF-8编码转换
2007/05/24 PHP
基于PHP生成静态页的实现方法
2013/05/10 PHP
使用session判断用户登录用户权限(超简单)
2013/06/08 PHP
浅析PKI加密解密 OpenSSL
2013/07/01 PHP
PHP将进程作为守护进程的方法
2015/03/19 PHP
PHP观察者模式原理与简单实现方法示例
2017/08/25 PHP
刷新时清空文本框内容的js代码
2007/04/23 Javascript
JS+css 图片自动缩放自适应大小
2013/08/08 Javascript
javascript实现div浮动在网页最顶上并带关闭按钮效果实例
2013/08/13 Javascript
用javascript读取xml文件读取节点数据
2014/08/12 Javascript
在JavaScript中正确引用bind方法的应用
2015/05/11 Javascript
js实现鼠标划过给div加透明度的方法
2015/05/25 Javascript
Spring Boot+AngularJS+BootStrap实现进度条示例代码
2017/03/02 Javascript
简单快速的实现js计算器功能
2017/08/17 Javascript
详解vue + vuex + directives实现权限按钮的思路
2017/10/24 Javascript
从零开始在NPM上发布一个Vue组件的方法步骤
2018/12/20 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
Echarts.js无法引入问题解决方案
2020/10/30 Javascript
使用Vant完成通知栏Notify的提示操作
2020/11/11 Javascript
Python中动态获取对象的属性和方法的教程
2015/04/09 Python
Python文本相似性计算之编辑距离详解
2016/11/28 Python
Python实现的堆排序算法原理与用法实例分析
2017/11/22 Python
Python sorted函数详解(高级篇)
2018/09/18 Python
django与小程序实现登录验证功能的示例代码
2019/02/19 Python
PyCharm导入python项目并配置虚拟环境的教程详解
2019/10/13 Python
工程部主管岗位职责
2013/11/17 职场文书
我读书我快乐演讲稿
2014/05/07 职场文书
征兵宣传标语
2014/06/20 职场文书
学校志愿者活动总结
2014/06/27 职场文书
2014年师德师风自我剖析材料
2014/09/27 职场文书
化工见习报告范文
2014/10/31 职场文书
英文升职感谢信
2015/01/23 职场文书
Python Django ORM连表正反操作技巧
2021/06/13 Python
《勇者辞职不干了》ED主题曲无字幕动画MV公开
2022/04/13 日漫