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的迭代器与生成器实例详解
Jul 16 Python
探究Python的Tornado框架对子域名和泛域名的支持
May 02 Python
对Python进行数据分析_关于Package的安装问题
May 22 Python
Django项目使用CircleCI的方法示例
Jul 14 Python
python 设置xlabel,ylabel 坐标轴字体大小,字体类型
Jul 23 Python
关于python导入模块import与常见的模块详解
Aug 28 Python
Python基于WordCloud制作词云图
Nov 29 Python
PyQt5多线程刷新界面防假死示例
Dec 13 Python
详解Python3中的 input() 函数
Mar 18 Python
Python 忽略文件名编码的方法
Aug 01 Python
Python爬虫模拟登陆哔哩哔哩(bilibili)并突破点选验证码功能
Dec 21 Python
如何使用python包中的sched事件调度器
Apr 30 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写杨辉三角实例代码
2011/07/17 PHP
PHP中的静态变量及static静态变量使用详解
2015/11/05 PHP
js png图片(有含有透明)在IE6中为什么不透明了
2010/02/07 Javascript
通过DOM脚本去设置样式信息
2010/09/19 Javascript
这些年、我收集的JQuery代码小结
2012/08/01 Javascript
GridView中获取被点击行中的DropDownList和TextBox中的值
2013/07/18 Javascript
ListBox实现上移,下移,左移,右移的简单实例
2014/02/13 Javascript
node.js中的fs.openSync方法使用说明
2014/12/17 Javascript
Javascript中实现trim()函数的两种方法
2015/02/04 Javascript
使用Script元素发送JSONP请求的方法
2016/06/12 Javascript
JS实现将Asp.Net的DateTime Json类型转换为标准时间的方法
2016/08/02 Javascript
jQuery表单对象属性过滤选择器实例详解
2016/09/13 Javascript
用 Vue.js 递归组件实现可折叠的树形菜单(demo)
2017/12/25 Javascript
Vue 框架之键盘事件、健值修饰符、双向数据绑定
2018/11/14 Javascript
微信小程序实现一张或多张图片上传(云开发)
2019/09/25 Javascript
[07:12]2014DOTA2西雅图国际邀请赛 黑马Liquid专题采访
2014/07/12 DOTA
浅谈python中截取字符函数strip,lstrip,rstrip
2015/07/17 Python
windows系统下Python环境的搭建(Aptana Studio)
2017/03/06 Python
利用Anaconda完美解决Python 2与python 3的共存问题
2017/05/25 Python
Python运维开发之psutil库的使用详解
2018/10/18 Python
python截取两个单词之间的内容方法
2018/12/25 Python
终于搞懂了Keras中multiloss的对应关系介绍
2020/06/22 Python
网页中的电话号码如何实现一键直呼效果_附示例
2016/03/15 HTML / CSS
LookFantastic丹麦:英国美容护肤精品在线商城
2016/08/18 全球购物
美国存储和组织商店:The Container Store
2017/08/16 全球购物
Solid & Striped官网:美国泳装品牌
2019/06/19 全球购物
Watchshop德国:欧洲在线手表No.1
2019/06/20 全球购物
珍珠鸟教学反思
2014/02/01 职场文书
听课评语大全
2014/04/30 职场文书
2014年母亲节演讲稿范文
2014/05/07 职场文书
小学生环保倡议书
2014/05/15 职场文书
同志主要表现材料
2014/08/21 职场文书
介绍信格式样本
2015/05/05 职场文书
2016年优秀团员事迹材料
2016/02/25 职场文书
Python pandas读取CSV文件的注意事项(适合新手)
2021/06/20 Python
mysql联合索引的使用规则
2021/06/23 MySQL