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 相关文章推荐
python3实现跳一跳点击跳跃
Jan 08 Python
Python实现使用卷积提取图片轮廓功能示例
May 12 Python
python控制windows剪贴板,向剪贴板中写入图片的实例
May 31 Python
对python mayavi三维绘图的实现详解
Jan 08 Python
Python实现的删除重复文件或图片功能示例【去重】
Apr 23 Python
python自制包并用pip免提交到pypi仅安装到本机【推荐】
Jun 03 Python
详解Python中的各种转义符\n\r\t
Jul 10 Python
详解有关PyCharm安装库失败的问题的解决方法
Feb 02 Python
Python Pandas数据分析工具用法实例
Nov 05 Python
详解pycharm自动import所需的库的操作方法
Nov 30 Python
浅谈Python列表嵌套字典转化的问题
Apr 07 Python
用Python生成会跳舞的美女
Jan 18 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数据 实现代码
2009/06/15 PHP
定义php常量的详解
2013/06/09 PHP
CodeIgniter使用phpcms模板引擎
2013/11/12 PHP
PHP使用GD库输出汉字的方法【测试可用】
2016/11/10 PHP
php模仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(中)
2017/06/11 PHP
Laravel 5.4向IoC容器中添加自定义类的方法示例
2017/08/15 PHP
PHP查找一列有序数组是否包含某值的方法
2020/02/07 PHP
FLASH 广告之外的链接
2008/12/16 Javascript
以JSON形式将JS中Array对象数组传至后台的方法
2014/01/06 Javascript
setinterval()与clearInterval()JS函数的调用方法
2015/01/21 Javascript
jQuery实现的经典滑动门效果
2015/09/22 Javascript
jquery动画效果学习笔记(8种效果)
2015/11/13 Javascript
vue-cli webpack 开发环境跨域详解
2017/05/18 Javascript
详解vue2.0的Element UI的表格table列时间戳格式化
2017/06/13 Javascript
JS与HTML结合实现流程进度展示条思路详解
2017/09/03 Javascript
使用InstantClick.js让页面提前加载200ms
2017/09/12 Javascript
基于nodejs的雪碧图制作工具的示例代码
2018/11/05 NodeJs
使用vuepress搭建静态博客的示例代码
2019/02/14 Javascript
微信小程序开发技巧汇总
2019/07/15 Javascript
[48:32]VGJ.T vs Fnatic 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[00:43]魔廷新尊——痛苦女王至宝捆绑包
2020/06/12 DOTA
python类继承用法实例分析
2015/05/27 Python
Python实现好友全头像的拼接实例(推荐)
2017/06/24 Python
numpy.std() 计算矩阵标准差的方法
2018/07/11 Python
python实现括号匹配的思路详解
2018/08/23 Python
python生成n个元素的全组合方法
2018/11/13 Python
在Matplotlib图中插入LaTex公式实例
2020/04/17 Python
Win 10下Anaconda虚拟环境的教程
2020/05/18 Python
马来西亚最热门的在线时尚商店:FashionValet
2018/11/11 全球购物
如何判断计算机可能已经中马
2013/03/22 面试题
应届生求职推荐信
2013/10/28 职场文书
适用于所有创业者的创业计划书
2014/02/05 职场文书
绿色家庭事迹材料
2014/05/01 职场文书
房产公证书
2015/01/23 职场文书
教师个人年度总结
2015/02/11 职场文书
团结友爱主题班会
2015/08/13 职场文书