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实现逻辑回归的方法示例
May 02 Python
Python 加密的实例详解
Oct 09 Python
python通过socket实现多个连接并实现ssh功能详解
Nov 08 Python
Python基于OpenCV实现视频的人脸检测
Jan 23 Python
Python浅复制中对象生存周期实例分析
Apr 02 Python
Falsk 与 Django 过滤器的使用与区别详解
Jun 04 Python
PyCharm专业最新版2019.1安装步骤(含激活码)
Oct 09 Python
Python 序列化和反序列化库 MarshMallow 的用法实例代码
Feb 25 Python
scrapy框架携带cookie访问淘宝购物车功能的实现代码
Jul 07 Python
pycharm激活方法到2099年(激活流程)
Sep 22 Python
python 深度学习中的4种激活函数
Sep 18 Python
python3实现飞机大战
Nov 29 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
20个2014年最优秀的PHP框架回顾
2014/10/22 PHP
PHP基于MySQL数据库实现对象持久层的方法
2015/06/17 PHP
使用一个for循环将N*N的二维数组的所有值置1实现方法
2017/05/29 PHP
PHP Laravel中的Trait使用方法
2019/01/20 PHP
PHP实现图片防盗链破解操作示例【解决图片防盗链问题/反向代理】
2020/05/29 PHP
Use Word to Search for Files
2007/06/15 Javascript
JQUERY THICKBOX弹出层插件
2008/08/30 Javascript
javascript 有趣而诡异的数组
2009/04/06 Javascript
Struts2的s:radio标签使用及用jquery添加change事件
2013/04/08 Javascript
Js为表单动态添加节点内容的方法
2015/02/10 Javascript
jQuery利用sort对DOM元素进行排序操作
2016/11/07 Javascript
EditPlus 正则表达式 实战(3)
2016/12/15 Javascript
JS遍历对象属性的方法示例
2017/01/10 Javascript
jquery.uploadifive插件怎么解决上传限制图片或文件大小问题
2017/05/08 jQuery
Bootstrap 模态框多次显示后台提交多次BUG的解决方法
2017/12/26 Javascript
细说webpack源码之compile流程-rules参数处理技巧(2)
2017/12/26 Javascript
js实现同一个页面,多个enter事件绑定的示例
2018/10/10 Javascript
vue 移动端适配方案详解
2018/11/15 Javascript
JS闭包经典实例详解
2018/12/20 Javascript
Vue实现input宽度随文字长度自适应操作
2020/07/29 Javascript
pip 错误unused-command-line-argument-hard-error-in-future解决办法
2014/06/01 Python
用Python实现斐波那契(Fibonacci)函数
2016/03/25 Python
node.js获取参数的常用方法(总结)
2017/05/29 Python
解决Python3.5+OpenCV3.2读取图像的问题
2018/12/05 Python
python查看文件大小和文件夹内容的方法
2019/07/08 Python
Python发送邮件封装实现过程详解
2020/05/09 Python
详解pandas映射与数据转换
2021/01/22 Python
美国南加州的原创极限运动潮牌:Vans(范斯)
2016/08/05 全球购物
巴西体育用品商店:Lojão dos Esportes
2018/07/21 全球购物
斯图尔特·韦茨曼鞋加拿大官网:Stuart Weitzman加拿大
2019/10/13 全球购物
医药营销个人求职信范文
2014/02/07 职场文书
民事赔偿协议书
2014/11/02 职场文书
小学一年级学生评语大全
2014/12/25 职场文书
2015年社区民政工作总结
2015/04/21 职场文书
Python中Cookies导出某站用户数据的方法
2021/05/17 Python
用Python生成会跳舞的美女
2022/01/18 Python