Python迭代和迭代器详解


Posted in Python onNovember 10, 2016

迭代器

迭代器(iterator)有时又称游标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如链表或阵列)上遍访的界面,设计人员无需关心容器物件的内存分配的实现细节。

摘自维基百科

也就是说迭代器类似于一个游标,卡到哪里就是哪里,可以通过这个来访问某个可迭代对象的元素;同时,也不是只有Python有这个特性。比如C++的STL中也有这个,如 vector<int>::iterator it 。下面主要说一下Python中的可迭代对象和迭代器吧。

Python可迭代对象(Iterable)

Python中经常使用 for 来对某个对象进行遍历,此时被遍历的这个对象就是可迭代对象,像常见的 list , tuple 都是。如果给一个准确的定义的话,就是只要它定义了可以返回一个迭代器的 __iter__ 方法,或者定义了可以支持下标索引的 __getitem__ 方法(这些双下划线方法会在其他章节中全面解释),那么它就是一个可迭代对象。

Python迭代器(iterator)

迭代器是通过 next() 来实现的,每调用一次他就会返回下一个元素,当没有下一个元素的时候返回一个 StopIteration 异常,所以实际上定义了这个方法的都算是迭代器。可以用通过下面例子来体验一下迭代器:

In [38]: s = 'ab'

In [39]: it = iter(s)

In [40]: it
Out[40]: <iterator at 0x1068e6d50>

In [41]: print it
<iterator object at 0x1068e6d50>

In [42]: it.next()
Out[42]: 'a'

In [43]: it.next()
Out[43]: 'b'

In [44]: it.next()
---------------------------------------------------------------------------
StopIteration               Traceback (most recent call last)
<ipython-input-44-54f0920595b2> in <module>()
----> 1 it.next()

StopIteration:

自己实现一个迭代器,如下(参见官网文档):

class Reverse:
  """Iterator for looping over a sequence backwards."""
  def __init__(self, data):
    self.data = data
    self.index = len(data)

  def __iter__(self):
    return self

  def next(self):
    if self.index == 0:
      raise StopIteration
    self.index = self.index - 1
    return self.data[self.index]

rev = Reverse('spam')
for char in rev:
  print char

[output]
m
a
p
s

生成器(Generators)

生成器是构造迭代器的最简单有力的工具,与普通函数不同的只有在返回一个值的时候使用 yield 来替代 return ,然后 yield 会自动构建好 next() 和 iter() 。是不是很省事。例如:

def reverse(data):
  for index in range(len(data)-1, -1, -1):
    yield data[index]

>>> for char in reverse('golf'):
...   print char
...
f
l
o
g

生成器最佳应用场景是:你不想同一时间将所有计算出来的大量结果集分配到内存当中,特别是结果集里还包含循环。比方说,循环打印1000000个数,我们一般会使用 xrange() 而不是 range() ,因为前者返回的是生成器,后者返回的是列表(列表消耗大量空间)。

Help on built-in function range in module __builtin__:

range(...)
  range(stop) -> list of integers
  range(start, stop[, step]) -> list of integers

  Return a list containing an arithmetic progression of integers.
  range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
  When step is given, it specifies the increment (or decrement).
  For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!
  These are exactly the valid indices for a list of 4 elements.

class xrange(object)
 | xrange(stop) -> xrange object
 | xrange(start, stop[, step]) -> xrange object
 |
 | Like range(), but instead of returning a list, returns an object that
 | generates the numbers in the range on demand. For looping, this is
 | slightly faster than range() and more memory efficient.
iter()

将可迭代对象转化为迭代器。

In [113]: s = 'abc'

In [114]: s.next()
---------------------------------------------------------------------------
AttributeError              Traceback (most recent call last)
<ipython-input-114-5e5e6532ea26> in <module>()
----> 1 s.next()

AttributeError: 'str' object has no attribute 'next'

In [115]: it = iter(s)

In [116]: it.next()
Out[116]: 'a'

生成器表达式

和列表推导式唯一的区别就是中括号换成了小括号,如下:

In [119]: num = (i for i in range(10))

In [120]: sum(num)
Out[120]: 45
Python 相关文章推荐
Python Trie树实现字典排序
Mar 28 Python
使用python编写android截屏脚本双击运行即可
Jul 21 Python
Python简单操作sqlite3的方法示例
Mar 22 Python
Python 自动化表单提交实例代码
Jun 08 Python
python模块之paramiko实例代码
Jan 31 Python
Python学习之Django的管理界面代码示例
Feb 10 Python
Python实现查看系统启动项功能示例
May 10 Python
python3 flask实现文件上传功能
Mar 20 Python
Python模块、包(Package)概念与用法分析
May 31 Python
Python-接口开发入门解析
Aug 01 Python
Python 实例方法、类方法、静态方法的区别与作用
Aug 14 Python
python爬虫豆瓣网的模拟登录实现
Aug 21 Python
python通过cookie模拟已登录状态的初步研究
Nov 09 #Python
Python内置函数OCT详解
Nov 09 #Python
windows10系统中安装python3.x+scrapy教程
Nov 08 #Python
简单谈谈python中的多进程
Nov 06 #Python
python自带的http模块详解
Nov 06 #Python
Python程序中设置HTTP代理
Nov 06 #Python
Python 搭建Web站点之Web服务器网关接口
Nov 06 #Python
You might like
兼容PHP5的PHP目录管理函数库
2008/07/10 PHP
Zend 输出产生XML解析错误
2009/03/03 PHP
php读取csv实现csv文件下载功能
2013/12/18 PHP
swoole和websocket简单聊天室开发
2017/11/18 PHP
PHP如何通过带尾指针的链表实现'队列'
2020/10/22 PHP
javascript实现动态CSS换肤技术的脚本
2007/06/29 Javascript
下载站控制介绍字数显示的脚本 显示全部 隐藏介绍等功能
2009/09/19 Javascript
20个非常棒的 jQuery 幻灯片插件和教程分享
2011/08/23 Javascript
javascript克隆对象深度介绍
2012/11/20 Javascript
ExtJS自定义主题(theme)样式详解
2013/11/18 Javascript
jQuery对Select的操作大集合(收藏)
2013/12/28 Javascript
淘宝网提供的国内NPM镜像简介和使用方法
2014/04/17 Javascript
jQuery中:image选择器用法实例
2015/01/03 Javascript
深入理解JavaScript系列(17):面向对象编程之概论详细介绍
2015/03/04 Javascript
JavaScript定时器制作弹窗小广告
2017/02/05 Javascript
JS实现动态修改table及合并单元格的方法示例
2017/02/20 Javascript
jQuery插件HighCharts实现的2D面积图效果示例【附demo源码下载】
2017/03/15 Javascript
深入理解Commonjs规范及Node模块实现
2017/05/17 Javascript
Angular4自制一个市县二级联动组件示例
2017/11/21 Javascript
浅谈使用React.setState需要注意的三点
2017/12/18 Javascript
html+jQuery实现拖动滑块图片拼图验证码插件【移动端适用】
2019/09/10 jQuery
Handtrack.js库实现实时监测手部运动(推荐)
2021/02/08 Javascript
python类中super()和__init__()的区别
2016/10/18 Python
python生成圆形图片的方法
2020/03/25 Python
Python数据分析之获取双色球历史信息的方法示例
2018/02/03 Python
Python实现钉钉发送报警消息的方法
2019/02/20 Python
Python opencv实现人眼/人脸识别以及实时打码处理
2019/04/29 Python
浅谈tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意点
2020/06/08 Python
Sephora丝芙兰澳洲官方网站:国际知名化妆品购物
2016/10/27 全球购物
美国领先的家居装饰和礼品商店:Kirkland’s
2017/01/30 全球购物
西班牙著名的珠宝首饰品牌:P D PAOLA
2018/09/15 全球购物
Dr.Jart+美国官网:韩国药妆品牌
2019/01/18 全球购物
最新销售员个人自荐信
2013/09/21 职场文书
美术教师个人总结
2015/02/06 职场文书
财政局个人年终总结
2015/03/03 职场文书
springboot 多数据源配置不生效遇到的坑及解决
2021/11/17 Java/Android