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简单生成随机数的方法示例
Mar 31 Python
python生成不重复随机数和对list乱序的解决方法
Apr 09 Python
使用pandas对矢量化数据进行替换处理的方法
Apr 11 Python
Python实现针对给定单链表删除指定节点的方法
Apr 12 Python
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
Apr 17 Python
Python堆排序原理与实现方法详解
May 11 Python
Python实现识别图片内容的方法分析
Jul 11 Python
Python图像处理之颜色的定义与使用分析
Jan 03 Python
浅谈Python 函数式编程
Jun 20 Python
Ubuntu权限不足无法创建文件夹解决方案
Nov 14 Python
Django集成MongoDB实现过程解析
Dec 01 Python
python glom模块的使用简介
Apr 13 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
VFP与其他应用程序的集成
2006/10/09 PHP
php动态生成JavaScript代码
2009/03/09 PHP
php用数组返回无限分类的列表数据的代码
2010/08/08 PHP
php SQL Injection with MySQL
2011/02/27 PHP
PHP配置把错误日志以邮件方式发送方法(Windows系统)
2015/06/23 PHP
php设置页面超时时间解决方法
2015/09/22 PHP
php处理抢购类功能的高并发请求
2018/02/08 PHP
php实现微信公众号创建自定义菜单功能的实例代码
2019/06/11 PHP
Aster vs KG BO3 第二场2.18
2021/03/10 DOTA
jQuery Tips 为AJAX回调函数传递额外参数的方法
2010/12/28 Javascript
基于jquery实现的文字向上跑动类似跑马灯的效果
2014/06/17 Javascript
jQuery中:reset选择器用法实例
2015/01/04 Javascript
jQuery通过控制节点实现仅在前台通过get方法完成参数传递
2015/02/02 Javascript
js实现键盘上下左右键选择文字并显示在文本框的方法
2015/05/07 Javascript
详解Bootstrap的aria-label和aria-labelledby应用
2016/01/04 Javascript
全面解析Javascript无限添加QQ好友原理
2016/06/15 Javascript
JavaScript中的this使用详解
2016/07/27 Javascript
node 命令方式启动修改端口的方法
2018/05/12 Javascript
JS使用Date对象实时显示当前系统时间简单示例
2018/08/23 Javascript
Nodejs中怎么实现函数的串行执行
2019/03/02 NodeJs
vue实现随机验证码功能(完整代码)
2019/12/10 Javascript
vue实现数据控制视图的原理解析
2020/01/07 Javascript
Angular短信模板校验代码
2020/09/23 Javascript
Python开发的HTTP库requests详解
2017/08/29 Python
Django实现快速分页的方法实例
2017/10/22 Python
Python语言检测模块langid和langdetect的使用实例
2019/02/19 Python
Python调用JavaScript代码的方法
2020/10/27 Python
详解CSS3的图层阴影和文字阴影效果使用
2016/06/09 HTML / CSS
关于HTML5语义标签的实践(blog页面)
2016/07/12 HTML / CSS
MAC彩妆英国官网:M·A·C UK
2018/05/30 全球购物
Omio荷兰:预订火车、巴士和机票
2018/11/04 全球购物
瑞典最大的儿童用品网上商店:pinkorblue.se
2021/03/09 全球购物
动物科学专业毕业生的自我评价
2013/11/29 职场文书
公司办公室岗位职责
2014/03/19 职场文书
学雷锋志愿者活动方案
2014/08/21 职场文书
收费员岗位职责
2015/02/14 职场文书