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的Flask框架中Flask-Admin库的简单入门指引
Apr 07 Python
Python的Django框架中自定义模版标签的示例
Jul 20 Python
Python 性能优化技巧总结
Nov 01 Python
python安装oracle扩展及数据库连接方法
Feb 21 Python
Python字典及字典基本操作方法详解
Jan 30 Python
Python3之读取连接过的网络并定位的方法
Apr 22 Python
python将字符串转换成json的方法小结
Jul 09 Python
关于Python中的向量相加和numpy中的向量相加效率对比
Aug 26 Python
python数据预处理 :数据共线性处理详解
Feb 24 Python
python 已知三条边求三角形的角度案例
Apr 12 Python
pytorch cuda上tensor的定义 以及减少cpu的操作详解
Jun 23 Python
Python基于Opencv识别两张相似图片
Apr 25 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
php检测图片木马多进制编程实践
2013/04/11 PHP
div移动 输入框不能输入的问题
2009/11/19 Javascript
javascript中JSON.parse()与eval()解析json的区别
2016/05/19 Javascript
jQuery学习笔记——jqGrid的使用记录(实现分页、搜索功能)
2016/11/09 Javascript
浅谈Angular的$q, defer, promise
2016/12/20 Javascript
js oncontextmenu事件使用详解
2017/03/25 Javascript
关于vue.js v-bind 的一些理解和思考
2017/06/06 Javascript
详解vee-validate的使用个人小结
2017/06/07 Javascript
JS从非数组对象转数组的方法小结
2018/03/26 Javascript
如何用JavaScript实现功能齐全的单链表详解
2019/02/11 Javascript
layui-select动态选中值的例子
2019/09/23 Javascript
详解vue-cli项目在IE浏览器打开报错解决方法
2020/12/10 Vue.js
[01:20:38]完美世界DOTA2联赛 GXR vs IO 第一场 11.07
2020/11/09 DOTA
Python实现的多线程端口扫描工具分享
2015/01/21 Python
django 开发忘记密码通过邮箱找回功能示例
2018/04/17 Python
Python实现使用卷积提取图片轮廓功能示例
2018/05/12 Python
python3实现SMTP发送邮件详细教程
2018/06/19 Python
解决win64 Python下安装PIL出错问题(图解)
2018/09/03 Python
Python爬虫之正则表达式的使用教程详解
2018/10/25 Python
Python实现删除排序数组中重复项的两种方法示例
2019/01/31 Python
Python3实现mysql连接和数据框的形成(实例代码)
2020/01/17 Python
使用 Python ssh 远程登陆服务器的最佳方案
2020/03/06 Python
Python3 webservice接口测试代码详解
2020/06/23 Python
CSS3 实现飘动的云朵动画
2020/12/01 HTML / CSS
台湾演唱会订票网站:StubHub台湾
2019/06/11 全球购物
英国银首饰公司:e&e Jewellery
2021/02/11 全球购物
和谐家庭演讲稿
2014/05/24 职场文书
党员四风问题个人对照检查材料
2014/10/26 职场文书
布达拉宫的导游词
2015/02/02 职场文书
企业百日安全活动总结
2015/05/07 职场文书
搞笑婚庆主持词
2015/06/29 职场文书
服装店员工管理制度
2015/08/07 职场文书
小学二年级班主任工作经验交流材料
2015/11/02 职场文书
goland设置颜色和字体的操作
2021/05/05 Golang
Apache Linkis 中间件架构及快速安装步骤
2022/03/16 Servers
Win10 Anaconda安装python-pcl
2022/04/29 Servers