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常见文件操作的函数示例代码
Nov 15 Python
python模拟登陆阿里妈妈生成商品推广链接
Apr 03 Python
python实现感知器
Dec 19 Python
Python Pandas找到缺失值的位置方法
Apr 12 Python
django 使用 request 获取浏览器发送的参数示例代码
Jun 11 Python
Python wxPython库使用wx.ListBox创建列表框示例
Sep 03 Python
用Python徒手撸一个股票回测框架搭建【推荐】
Aug 05 Python
python tkinter控件布局项目实例
Nov 04 Python
python通过opencv实现图片裁剪原理解析
Jan 19 Python
基于Python和C++实现删除链表的节点
Jul 06 Python
Python实现画图软件功能方法详解
Jul 28 Python
Django搭建项目实战与避坑细节详解
Dec 06 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
客户端静态页面玩分页
2006/06/26 Javascript
得到文本框选中的文字,动态插入文字的js代码
2007/03/07 Javascript
javascript indexOf函数使用说明
2008/07/03 Javascript
用Javascript数组处理多个字符串的连接问题
2009/08/20 Javascript
基于jquery的获取mouse坐标插件的实现代码
2010/04/01 Javascript
JavaScript入门之基本函数详解
2011/10/21 Javascript
查看大图功能代码jquery版
2013/11/05 Javascript
js AppendChild与insertBefore用法详细对比
2013/12/16 Javascript
更快的异步执行(setTimeout多浏览器)
2014/08/12 Javascript
jQuery实现流动虚线框的方法
2015/01/29 Javascript
JS+CSS实现Li列表隔行换色效果的方法
2015/02/16 Javascript
jQuery使用toggleClass方法动态添加删除Class样式的方法
2015/03/26 Javascript
学习JavaScript设计模式(单例模式)
2015/11/26 Javascript
javascript瀑布流式图片懒加载实例
2020/06/28 Javascript
JS设置cookie、读取cookie
2016/02/24 Javascript
用JS实现图片轮播效果代码(一)
2016/06/26 Javascript
原生js图片轮播效果实现代码
2016/10/19 Javascript
JavaScript中 DOM操作方法小结
2017/04/25 Javascript
AngularJS使用ui-route实现多层嵌套路由的示例
2018/01/10 Javascript
jquery实现点击a链接,跳转之后,该a链接处显示背景色的方法
2018/01/18 jQuery
详解Python中dict与set的使用
2015/08/10 Python
python多维数组切片方法
2018/04/13 Python
对Python 网络设备巡检脚本的实例讲解
2018/04/22 Python
python3利用venv配置虚拟环境及过程中的小问题小结
2018/08/01 Python
计算机二级python学习教程(3) python语言基本数据类型
2019/05/16 Python
Python整数与Numpy数据溢出问题解决
2019/09/11 Python
Python列表操作方法详解
2020/02/09 Python
Python将QQ聊天记录生成词云的示例代码
2021/02/10 Python
HTML5+CSS3 实现灵动的动画 TAB 切换效果(DEMO)
2017/09/15 HTML / CSS
老板电器官方购物商城:老板油烟机、燃气灶、消毒柜、电烤箱
2018/05/30 全球购物
HEMA英国:荷兰原创设计
2018/08/28 全球购物
维氏瑞士军刀英国网站:Victorinox英国
2019/07/04 全球购物
质量保证书范本
2014/04/29 职场文书
2014优秀党员事迹材料
2014/08/14 职场文书
领导欢迎词范文
2015/01/26 职场文书
解决Vue+SpringBoot+Shiro跨域问题
2021/06/09 Vue.js