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的Cookie.py模块支持冒号做key的方法
Dec 28 Python
python基础教程之基本内置数据类型介绍
Feb 20 Python
在Python中实现shuffle给列表洗牌
Nov 08 Python
利用Django提供的ModelForm增删改数据的方法
Jan 06 Python
Django框架实现分页显示内容的方法详解
May 10 Python
python程序变成软件的实操方法
Jun 24 Python
Python 操作mysql数据库查询之fetchone(), fetchmany(), fetchall()用法示例
Oct 17 Python
Python函数的返回值、匿名函数lambda、filter函数、map函数、reduce函数用法实例分析
Dec 26 Python
如何使用Python处理HDF格式数据及可视化问题
Jun 24 Python
python绘图pyecharts+pandas的使用详解
Dec 13 Python
Python爬取你好李焕英豆瓣短评生成词云的示例代码
Feb 24 Python
一篇文章带你搞懂Python类的相关知识
May 20 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的FTP学习(一)[转自奥索]
2006/10/09 PHP
global.php
2006/12/09 PHP
PHP中抽象类、接口的区别与选择分析
2016/03/29 PHP
发一个自己用JS写的实用看图工具实现代码
2008/07/26 Javascript
JQuery 学习笔记 选择器之一
2009/07/23 Javascript
Javascript调用C#代码
2011/01/17 Javascript
jquery里的正则表达式说明
2011/08/03 Javascript
图片img的src不变让浏览器重新加载实现方法
2013/03/29 Javascript
通过url查找a元素并点击
2014/04/09 Javascript
选择复选框按钮置灰否则按钮可用
2014/05/22 Javascript
node.js中的fs.fsync方法使用说明
2014/12/15 Javascript
JavaScript中的Math.sin()方法使用详解
2015/06/15 Javascript
jQuery实现拖动剪裁图片作为头像
2016/12/28 Javascript
Bootstrap jquery.twbsPagination.js动态页码分页实例代码
2017/02/20 Javascript
微信小程序page的生命周期和音频播放及监听实例详解
2017/04/07 Javascript
详解微信小程序 通过控制CSS实现view隐藏与显示
2017/05/24 Javascript
详解vue.js 开发环境搭建最简单攻略
2017/06/12 Javascript
React Native 环境搭建的教程
2017/08/19 Javascript
10个经典的网页鼠标特效代码
2018/01/09 Javascript
基于node打包可执行文件工具_Pkg使用心得分享
2018/01/24 Javascript
[15:46]教你分分钟做大人——沙王
2015/03/11 DOTA
[48:30]LGD vs infamous Supermajor小组赛D组 BO3 第一场 6.3
2018/06/04 DOTA
[04:45]DOTA2-DPC中国联赛正赛 iG vs LBZS 赛后选手采访
2021/03/11 DOTA
python+matplotlib实现礼盒柱状图实例代码
2018/01/16 Python
对Python的交互模式和直接运行.py文件的区别详解
2019/06/29 Python
什么是python的必选参数
2020/06/21 Python
pycharm 复制代码出现空格的解决方式
2021/01/15 Python
贝佳斯官方网站:Borghese
2020/05/08 全球购物
加拿大拼图大师:Puzzle Master
2020/12/28 全球购物
Servlet的实例是在生命周期什么时候创建的?配置servlet最重要的是什么?
2012/05/30 面试题
毕业自我鉴定范文
2013/11/06 职场文书
个人社会实践自我鉴定
2014/03/24 职场文书
高中学校对照检查材料
2014/08/31 职场文书
高中毕业典礼演讲稿
2014/09/09 职场文书
2016党员发展对象培训心得体会
2016/01/08 职场文书
一级电子管军用接收机测评
2022/04/05 无线电