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 相关文章推荐
Django中模型Model添加JSON类型字段的方法
Jun 17 Python
python开发之thread实现布朗运动的方法
Nov 11 Python
Python爬虫包 BeautifulSoup  递归抓取实例详解
Jan 28 Python
python实现批量修改文件名代码
Sep 10 Python
Python实现基本数据结构中队列的操作方法示例
Dec 04 Python
Python3之文件读写操作的实例讲解
Jan 23 Python
Python字符串逆序输出的实例讲解
Feb 16 Python
使用python无账号无限制获取企查查信息的实例代码
Apr 17 Python
30行Python代码实现高分辨率图像导航的方法
May 22 Python
Python如何telnet到网络设备
Feb 18 Python
Python中使用Lambda函数的5种用法
Apr 01 Python
python实现进度条的多种实现
Apr 29 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中的多行字符串传递给JavaScript的两种方法
2014/06/19 PHP
ThinkPHP实现动态包含文件的方法
2014/11/29 PHP
php获取用户浏览器版本的方法
2015/01/03 PHP
PHP 设计模式系列之 specification规格模式
2016/01/10 PHP
CakePHP框架Session设置方法分析
2017/02/23 PHP
TNC vs BOOM BO3 第二场2.13
2021/03/10 DOTA
JavaScript 动态改变图片大小
2009/06/11 Javascript
如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙
2011/03/03 Javascript
Jquery中对数组的操作代码
2011/08/12 Javascript
js实现的仿新浪微博完美的时间组件升级版
2011/12/20 Javascript
js制作简易年历完整实例
2015/01/28 Javascript
jquery悬浮提示框完整实例
2016/01/13 Javascript
JavaScript DOM 对象深入了解
2016/07/20 Javascript
Bootstrap基本插件学习笔记之折叠(22)
2016/12/08 Javascript
ES6概念 ymbol.for()方法
2016/12/25 Javascript
JavaScript实现星星等级评价功能
2017/03/22 Javascript
web.js.字符串与正则表达式操作
2017/05/13 Javascript
vue监听scroll的坑的解决方法
2017/09/07 Javascript
JS实现常见的查找、排序、去重算法示例
2018/05/21 Javascript
js删除数组中某几项的方法总结
2019/01/16 Javascript
解决vue项目中页面调用数据 在数据加载完毕之前出现undefined问题
2019/11/14 Javascript
JavaScript缺少insertAfter解决方案
2020/07/03 Javascript
python清除字符串里非数字字符的方法
2015/07/02 Python
python numpy格式化打印的实例
2018/05/14 Python
pandas 根据列的值选取所有行的示例
2018/11/07 Python
python二维键值数组生成转json的例子
2019/12/06 Python
基于python traceback实现异常的获取与处理
2019/12/13 Python
CSS3实现点击放大的动画实例代码
2017/02/27 HTML / CSS
美国领先的家居装饰和礼品商店:Kirkland’s
2017/01/30 全球购物
信息部岗位职责
2013/11/12 职场文书
新闻发布会策划方案
2014/06/12 职场文书
财务工作检讨书
2014/10/29 职场文书
2015世界地球日活动总结
2015/02/09 职场文书
《作风建设永远在路上》心得体会
2016/01/21 职场文书
iPhone13将有八大升级
2021/04/15 数码科技
《火纹风花雪月无双》预告“神秘雇佣兵” 紫发剑客
2022/04/13 其他游戏