Python中的迭代器漫谈


Posted in Python onFebruary 03, 2015

问题是在Python中进行循环的时候产生的,熟悉Python的都知道,它没有类似其它语言中的for循环, 只能通过for in的方式进行循环遍历。最典型的应用就是通过range函数产生一个列表,然后用for in进行操作,如下:

#!/usr/bin/env python

for i in range(10):

    print i

代码的意义很好理解,range会产生一个列表,用for in最这个列表进行遍历,就有和类似for(i = 0;i<n;i++)同样的效果,range函数的详解可以看这里。问题又来了,range这个对象会产生一个列表,那么这个列表的内容铁定是存放在内存当中的,当需要的循环数量太大时,是相当占用内存的, 为了统计使用range占用内存的情况,我做了6次使用,分别用range产生100,10000,100000,1000000,10000000,100000000长度的列表,然后统计内存的占用:

测试代码 占用内存

range(100) 2.0MB

range(10000) 2.2MB

range(100000) 3.8MB

range(1000000) 19.5MB

range(10000000) 168.5MB

range(100000000) 1465.8MB

可以看到,随着基数的加大,占用内存呈几何倍数增加,显然在进行大循环操作的时候,要避免使用range。

为了解决上述问题,python提供了另外一个函数xrange,这个函数和range非常相似,但是占用内存比range会小很多,相关的说明可以查看这里,经过测试,用xrange产生的对象,不管参数是多少,占用内存几乎都没有变化。问题又来了,xrange内部是如何实现的,为什么和range性能相差这么大?为了验证我的猜想,先尝试用python实现类似xrange的函数zrange:

#!/usr/bin/env python

class zrange(object):

    def __init__(self,stop):

        self.__pointer=0

        self.stop=stop

    def __iter__(self):  

        return self  

    def next(self): #python3.0中,改用__next__

        if self.__pointer  >= self.stop:

            raise StopIteration

        else:

            self.__pointer = self.__pointer + 1

            return self.__pointer-1

test = zrange(10000000)

for i in test:

    print i

运行的结果和xrange一样, 对zrange进行内存占用测试,发现和xrange一样,参数的大小对内存占用几乎没有影响。那么它和range的区别在哪里呢?

前面说到,range产生的是一个列表,而无论是自定义的zrange还是系统内置的xrange产生的都是一个对象,像xrange或者zrange产生的对象,就叫做可迭代对象, 它给外部提供了一种遍历其内部元素,而不用关心其内部实现的方法。上面zrange的实现中, 最关键的实现是建立了一个内部指针__pointer, 它记录当前的访问的位置, 下次的访问就可以通过指针的状态进行相应的操作。

Python或者其它语言中,还有很多类似通过迭代的方式访问对象内容的,如读取一个文件中的内容:

#!/usr/bin/env python

f = open('zrange.py','r')

while True:

    line = f.readline()

    if not line:

        break

    print line.strip()

f.close()

大家都知道用readline要比reandlines节省资源,其实readline和readlines就类似于xrange和range,一个是通过指针记录当前位置,下次访问把指针往前移动一个单位,另外一个是直接把所有内容存放到内存当中。文件操作函数中,还可以通过seek手动的调整指针的位置,从而达到跳过或者重复读取某些内容的目的。

可以说,迭代器的实现中,其内部指针是节省资源,让迭代正常运行的关键。

Python 相关文章推荐
Python实现基于多线程、多用户的FTP服务器与客户端功能完整实例
Aug 18 Python
Python读取MRI并显示为灰度图像实例代码
Jan 03 Python
详解python使用递归、尾递归、循环三种方式实现斐波那契数列
Jan 16 Python
python 实现在Excel末尾增加新行
May 02 Python
Python处理菜单消息操作示例【基于win32ui模块】
May 09 Python
Python2和Python3的共存和切换使用
Apr 12 Python
Python实现 PS 图像调整中的亮度调整
Jun 28 Python
python匿名函数用法实例分析
Aug 03 Python
利用python list完成最简单的DB连接池方法
Aug 09 Python
Python数据分析模块pandas用法详解
Sep 04 Python
Python实现基于socket的udp传输与接收功能详解
Nov 15 Python
解决tensorflow 释放图,删除变量问题
Jun 23 Python
Python描述器descriptor详解
Feb 03 #Python
理解Python中的With语句
Feb 02 #Python
Linux环境下MySQL-python安装过程分享
Feb 02 #Python
Python中用pycurl监控http响应时间脚本分享
Feb 02 #Python
Python列表(list)常用操作方法小结
Feb 02 #Python
Python Sleep休眠函数使用简单实例
Feb 02 #Python
Python中实现从目录中过滤出指定文件类型的文件
Feb 02 #Python
You might like
PHP初学者头疼问题总结
2006/07/08 PHP
php 无法加载mcrypt.dll的解决办法
2013/04/03 PHP
php格式化电话号码的方法
2015/04/24 PHP
php实现通过stomp协议连接ActiveMQ操作示例
2020/02/23 PHP
javascript中利用数组实现的循环队列代码
2010/01/24 Javascript
给文字加上着重号的JS代码
2013/11/12 Javascript
JavaScript声明变量时为什么要加var关键字
2014/09/29 Javascript
javascript制作坦克大战全纪录(1)
2014/11/27 Javascript
node.js中的fs.futimes方法使用说明
2014/12/17 Javascript
easyUI实现(alert)提示框自动关闭的实例代码
2016/11/07 Javascript
JavaScript数据类型和变量_动力节点Java学院整理
2017/06/26 Javascript
微信小程序swiper实现滑动放大缩小效果
2018/11/15 Javascript
vue基础之data存储数据及v-for循环用法示例
2019/03/08 Javascript
js this 绑定机制深入详解
2020/04/30 Javascript
vue中全局路由守卫中替代this操作(this.$store/this.$vux)
2020/07/24 Javascript
详解 javascript对象创建模式
2020/10/30 Javascript
剖析Python的Twisted框架的核心特性
2016/05/25 Python
Flask框架的学习指南之开发环境搭建
2016/11/20 Python
Python OpenCV读取png图像转成jpg图像存储的方法
2018/10/28 Python
python对矩阵进行转置的2种处理方法
2019/07/17 Python
Django实现文件上传和下载功能
2019/10/06 Python
Python astype(np.float)函数使用方法解析
2020/06/08 Python
keras中epoch,batch,loss,val_loss用法说明
2020/07/02 Python
python报错TypeError: ‘NoneType‘ object is not subscriptable的解决方法
2020/11/05 Python
详解android与HTML混合开发总结
2018/06/06 HTML / CSS
英国最大的独立摄影零售商:Park Cameras
2019/11/27 全球购物
Ever New美国:澳大利亚领先的女装时尚品牌
2019/11/28 全球购物
FirstCry阿联酋儿童和婴儿产品网上购物:FirstCry.ae
2021/02/22 全球购物
加拿大探亲邀请信
2014/01/28 职场文书
《小池塘》教学反思
2014/02/28 职场文书
大学生创业计划书怎么写
2014/09/15 职场文书
交警失职检讨书
2015/01/26 职场文书
推广普通话主题班会
2015/08/17 职场文书
小学班长竞选稿
2015/11/20 职场文书
2016中学教师读书心得体会
2016/01/13 职场文书
《认识钟表》教学反思
2016/02/16 职场文书