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操作MongoDB基础知识
Nov 01 Python
深入理解NumPy简明教程---数组2
Dec 17 Python
使用PyInstaller将python转成可执行文件exe笔记
May 26 Python
python实现RabbitMQ的消息队列的示例代码
Nov 08 Python
python输出决策树图形的例子
Aug 09 Python
python 实现绘制整齐的表格
Nov 18 Python
Python3搭建http服务器的实现代码
Feb 11 Python
如何基于python3和Vue实现AES数据加密
Mar 27 Python
python求numpy中array按列非零元素的平均值案例
Jun 08 Python
Python使用grequests并发发送请求的示例
Nov 05 Python
史上最详细的Python打包成exe文件教程
Jan 17 Python
深入浅析python3 依赖倒置原则(示例代码)
Jul 09 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乱码问题,UTF-8乱码常见问题小结
2012/04/09 PHP
基于php验证码函数的使用示例
2013/05/03 PHP
php发送短信验证码完成注册功能
2015/11/24 PHP
php慢查询日志和错误日志使用详解
2021/02/27 PHP
javascript中的location用法简单介绍
2007/03/07 Javascript
表单(FORM)的一些实用效果代码
2007/03/25 Javascript
Jquery下的26个实用小技巧(jQuery tips, tricks &amp; solutions)
2010/03/01 Javascript
如何制作浮动广告 JavaScript制作浮动广告代码
2012/12/30 Javascript
jquery中使用$(#form).submit()重写提交表单无效原因分析及解决
2013/03/25 Javascript
jquery 单引号和双引号的区别及使用注意
2013/07/31 Javascript
javascript实现回车键提交表单方法总结
2015/01/10 Javascript
js简单工厂模式用法实例
2015/06/30 Javascript
JavaScript SHA512加密算法详细代码
2016/10/06 Javascript
关于Vue组件库开发详析
2018/07/01 Javascript
vue2中引用及使用 better-scroll的方法详解
2018/11/15 Javascript
如何用RxJS实现Redux Form
2018/12/29 Javascript
mpvue微信小程序的接口请求fly全局拦截代码实例
2019/11/13 Javascript
详解vue-flickity的fullScreen功能实现
2020/04/07 Javascript
Element Dropdown下拉菜单的使用方法
2020/07/26 Javascript
python实现多线程抓取知乎用户
2016/12/12 Python
在python中实现将一张图片剪切成四份的方法
2018/12/05 Python
Python3多目标赋值及共享引用注意事项
2019/05/27 Python
由面试题加深对Django的认识理解
2019/07/19 Python
简单了解python数组的基本操作
2019/11/26 Python
python GUI库图形界面开发之PyQt5滚动条控件QScrollBar详细使用方法与实例
2020/03/06 Python
Django实现将一个字典传到前端显示出来
2020/04/03 Python
python能做哪些生活有趣的事情
2020/09/09 Python
校庆团日活动总结
2014/08/28 职场文书
四风问题班子对照检查材料
2014/09/27 职场文书
大学生团员个人总结
2015/02/14 职场文书
调解协议书范本
2016/03/21 职场文书
告诉你一个秘密:富人致富的五大优点
2019/07/11 职场文书
CSS 文字装饰 text-decoration & text-emphasis 详解
2021/04/06 HTML / CSS
React列表栏及购物车组件使用详解
2021/06/28 Javascript
「我的青春恋爱物语果然有问题。-妄言录-」第20卷封面公开
2022/03/21 日漫
vue数据字典取键值项目的字典问题
2022/04/12 Vue.js