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 基础学习教程
Feb 08 Python
使用python将mdb数据库文件导入postgresql数据库示例
Feb 17 Python
Python中使用ElementTree解析XML示例
Jun 02 Python
Tensorflow实现卷积神经网络的详细代码
May 24 Python
Python3实现的判断环形链表算法示例
Mar 07 Python
python之pyqt5通过按钮改变Label的背景颜色方法
Jun 13 Python
python 变量初始化空列表的例子
Nov 28 Python
Python箱型图处理离群点的例子
Dec 09 Python
Python使用ElementTree美化XML格式的操作
Mar 06 Python
Python json转字典字符方法实例解析
Apr 13 Python
Python数组拼接np.concatenate实现过程
Apr 18 Python
利用python绘制正态分布曲线
Jan 04 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 print类函数使用总结
2010/06/25 PHP
CI框架学习笔记(一) - 环境安装、基本术语和框架流程
2014/10/26 PHP
PHP单例模式定义与使用实例详解
2017/02/06 PHP
Laravel 创建指定表 migrate的例子
2019/10/09 PHP
css把超出的部分显示为省略号的方法兼容火狐
2008/07/23 Javascript
使用js检测浏览器的实现代码
2013/05/14 Javascript
Textarea根据内容自适应高度
2013/10/28 Javascript
JavaScript获取flash对象与网上的有所不同
2014/04/21 Javascript
JavaScript中操作字符串小结
2015/05/04 Javascript
js脚本分页代码分享(7种样式)
2015/08/19 Javascript
javascript实现随机显示星星特效
2016/01/28 Javascript
利用JS实现文字的聚合动画效果
2017/01/22 Javascript
在React 组件中使用Echarts的示例代码
2017/11/08 Javascript
利用js给datalist或select动态添加option选项的方法
2018/01/25 Javascript
Angular5中提取公共组件之radio list的实例代码
2018/07/10 Javascript
react-native使用leanclound消息推送的方法
2018/08/06 Javascript
使用vue自定义指令开发表单验证插件validate.js
2019/05/23 Javascript
使用typescript改造koa开发框架的实现
2020/02/04 Javascript
Python实现从url中提取域名的几种方法
2014/09/26 Python
Python中使用插入排序算法的简单分析与代码示例
2016/05/04 Python
Python如何读取MySQL数据库表数据
2017/03/11 Python
python在线编译器的简单原理及简单实现代码
2018/02/02 Python
python+mysql实现教务管理系统
2019/02/20 Python
详解Python3网络爬虫(二):利用urllib.urlopen向有道翻译发送数据获得翻译结果
2019/05/07 Python
windows下Pycharm安装opencv的多种方法
2020/03/05 Python
Python面向对象程序设计之静态方法、类方法、属性方法原理与用法分析
2020/03/23 Python
Pycharm IDE的安装和使用教程详解
2020/04/30 Python
Python使用requests模块爬取百度翻译
2020/08/25 Python
中国跨境电商:Tomtop
2017/03/16 全球购物
劳动模范事迹材料
2014/01/19 职场文书
最美孝心少年事迹材料
2014/08/15 职场文书
2015年文明创建工作总结
2015/04/30 职场文书
2016年“抗战胜利纪念日”71周年校园广播稿
2015/12/18 职场文书
Python实现拼音转换
2021/06/07 Python
Win11运行育碧游戏总是崩溃怎么办 win11玩育碧游戏出现性能崩溃的解决办法
2022/04/06 数码科技
二维码条形码生成的JavaScript脚本库
2022/07/07 Javascript