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中用于计算指数的exp()方法
May 14 Python
不可错过的十本Python好书
Jul 06 Python
Python元组常见操作示例
Feb 19 Python
python字符串循环左移
Mar 08 Python
Python3连接Mysql8.0遇到的问题及处理步骤
Feb 17 Python
python 回溯法模板详解
Feb 26 Python
python使用pandas抽样训练数据中某个类别实例
Feb 28 Python
Python基于requests库爬取网站信息
Mar 02 Python
python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析
Mar 08 Python
pandas中的ExcelWriter和ExcelFile的实现方法
Apr 24 Python
在python中使用pyspark读写Hive数据操作
Jun 06 Python
使用darknet框架的imagenet数据分类预训练操作
Jul 07 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
常用星际术语索引(新手指南)
2020/03/04 星际争霸
五款常用mysql slow log分析工具的比较分析
2011/05/22 PHP
深入php中var_dump方法的使用详解
2013/06/24 PHP
PHP四舍五入、取整、round函数使用示例
2015/02/06 PHP
php接口数据加密、解密、验证签名
2015/03/12 PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
2017/06/20 PHP
Laravel框架基础语法与知识点整理【模板变量、输出、include引入子视图等】
2019/12/03 PHP
ExtJs之带图片的下拉列表框插件
2010/03/04 Javascript
JS幻灯片可循环播放可平滑旋转带滚动导航(自写)
2013/08/05 Javascript
js setTimeout 参数传递使用介绍
2013/08/13 Javascript
Jquery解析Json格式数据过程代码
2014/10/17 Javascript
js给网页加上背景音乐及选择音效的方法
2015/03/03 Javascript
JavaScript让Textarea支持tab按键的方法
2015/06/26 Javascript
JSON相关知识汇总
2015/07/03 Javascript
纯HTML5制作围住神经猫游戏-附源码下载
2015/08/23 Javascript
深入理解JavaScript函数参数(推荐)
2016/07/26 Javascript
jQuery实现弹出带遮罩层的居中浮动窗口效果
2016/09/12 Javascript
浅谈javascript:两种注释,声明变量,定义函数
2016/09/29 Javascript
浅谈js对象属性 通过点(.) 和方括号([]) 的不同之处
2016/10/29 Javascript
原生js jquery ajax请求以及jsonp的调用方法
2017/08/04 jQuery
JavaScript中防止微信浏览器被整体拖动的方法
2017/08/25 Javascript
Django中使用jquery的ajax进行数据交互的实例代码
2017/10/15 jQuery
Node.js+Express+Mysql 实现增删改查
2019/04/03 Javascript
用Python展示动态规则法用以解决重叠子问题的示例
2015/04/02 Python
详解python中executemany和序列的使用方法
2017/08/12 Python
Python合并多个Excel数据的方法
2018/07/16 Python
详解Django定时任务模块设计与实践
2019/07/24 Python
如何使用css3实现一个类在线直播的队列动画的示例代码
2020/06/17 HTML / CSS
英国和国际包裹递送:ParcelCompare
2019/08/26 全球购物
linux面试题参考答案(6)
2016/06/23 面试题
计算机毕业大学生推荐信
2013/12/01 职场文书
2015年求职自荐信范文
2015/03/04 职场文书
教研活动主持词
2015/07/03 职场文书
60条职场经典语录,总有一条能触动你的心
2019/08/21 职场文书
django项目、vue项目部署云服务器的详细过程
2022/07/23 Servers
Vue router配置与使用分析讲解
2022/12/24 Vue.js