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实现bucket排序算法实例分析
May 04 Python
Python多线程扫描端口代码示例
Feb 09 Python
对Python中的@classmethod用法详解
Apr 21 Python
Linux下python3.6.1环境配置教程
Sep 26 Python
libreoffice python 操作word及excel文档的方法
Jul 04 Python
Django Rest framework频率原理与限制
Jul 26 Python
python中time库的实例使用方法
Oct 31 Python
win10下python2和python3共存问题解决方法
Dec 23 Python
Python numpy矩阵处理运算工具用法汇总
Jul 13 Python
Python如何实现机器人聊天
Sep 10 Python
scrapy处理python爬虫调度详解
Nov 23 Python
Python爬虫 简单介绍一下Xpath及使用
Apr 26 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+mysql一个名片库程序
2006/10/09 PHP
使用数据库保存session的方法
2006/10/09 PHP
PHP 代码规范小结
2012/03/08 PHP
thinkphp微信开之安全模式消息加密解密不成功的解决办法
2015/12/02 PHP
PHP环境搭建的详细步骤
2016/06/30 PHP
Yii2针对游客、用户防范规则和限制的解决方法分析
2016/10/08 PHP
Smarty模板配置实例简析
2019/07/20 PHP
laravel 中某一字段自增、自减的例子
2019/10/11 PHP
jQuery LigerUI 插件介绍及使用之ligerDrag和ligerResizable示例代码打包
2011/04/06 Javascript
一个简单的JS鼠标悬停特效具体方法
2013/06/17 Javascript
JavaScript通过prototype给对象定义属性用法实例
2015/03/23 Javascript
JavaScript中日常收集常见的10种错误(推荐)
2017/01/08 Javascript
bootstrap输入框组使用方法
2017/02/07 Javascript
Vue 实现双向绑定的四种方法
2018/03/16 Javascript
vue实现点击展开点击收起效果
2018/04/27 Javascript
vue实现动态列表点击各行换色的方法
2018/09/13 Javascript
详解使用JWT实现单点登录(完全跨域方案)
2019/08/02 Javascript
解决vue项目刷新后,导航菜单高亮显示的位置不对问题
2019/11/01 Javascript
Element-ui upload上传文件限制的解决方法
2021/01/22 Javascript
原生微信小程序开发中 redux 的使用详解
2021/02/18 Javascript
python sqlobject(mysql)中文乱码解决方法
2008/11/14 Python
python中将字典转换成其json字符串
2014/07/16 Python
Python性能优化技巧
2015/03/09 Python
Python中return语句用法实例分析
2015/08/04 Python
python的多重继承的理解
2017/08/06 Python
Python中输入和输出(打印)数据实例方法
2019/10/13 Python
基于python实现把图片转换成素描
2019/11/13 Python
解决Python使用列表副本的问题
2019/12/19 Python
详解python logging日志传输
2020/07/01 Python
实习生的自我鉴定范文欣赏
2013/11/20 职场文书
校庆筹备方案
2014/03/30 职场文书
预防传染病方案
2014/06/14 职场文书
2015年少先队活动总结
2015/03/25 职场文书
在酒桌上的敬酒词
2015/08/12 职场文书
2019数学教师下学期工作总结
2019/06/27 职场文书
在redisCluster中模糊获取key方式
2021/07/09 Redis