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开发的单词频率统计工具wordsworth使用方法
Jun 25 Python
python 划分数据集为训练集和测试集的方法
Dec 11 Python
Python装饰器基础概念与用法详解
Dec 22 Python
实例讲解Python中整数的最大值输出
Mar 17 Python
python查询文件夹下excel的sheet名代码实例
Apr 02 Python
pytorch 可视化feature map的示例代码
Aug 20 Python
python 实现dict转json并保存文件
Dec 05 Python
pytorch:torch.mm()和torch.matmul()的使用
Dec 27 Python
python解析多层json操作示例
Dec 30 Python
通过代码简单了解django model序列化作用
Nov 12 Python
Python爬虫之Selenium实现关闭浏览器
Dec 04 Python
基于Python的接口自动化unittest测试框架和ddt数据驱动详解
Jan 27 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简介
2006/10/09 PHP
PHP 图片上传实现代码 带详细注释
2010/04/29 PHP
九个你必须知道而且又很好用的php函数和特点
2013/08/08 PHP
php基于 swoole 实现的异步处理任务功能示例
2019/08/13 PHP
JavaScript面向对象知识串结(读JavaScript高级程序设计(第三版))
2012/07/17 Javascript
js事件冒泡实例分享(已测试)
2013/04/23 Javascript
JavaScript实现两个Table固定表头根据页面大小自行调整
2014/01/03 Javascript
javascript数组遍历for与for in区别详解
2014/12/04 Javascript
jQuery实现单击和鼠标感应事件
2015/02/01 Javascript
javascript中var的重要性分析
2015/02/11 Javascript
jQuery给动态添加的元素绑定事件的方法
2015/03/09 Javascript
jquery简单实现网页层的展开与收缩效果
2015/08/07 Javascript
推荐阅读的js快速判断IE浏览器(兼容IE10与IE11)
2015/12/13 Javascript
基于MVC4+EasyUI的Web开发框架形成之旅之界面控件的使用
2015/12/16 Javascript
jQuery实现分页功能(含ajax请求、后台数据、附完整demo)
2017/04/03 jQuery
Vue2.0子同级组件之间数据交互方法
2018/02/28 Javascript
对Angular中单向数据流的深入理解
2018/03/31 Javascript
Echarts之悬浮框中的数据排序问题
2018/11/08 Javascript
关于微信公众号开发无法支付的问题解决
2018/12/28 Javascript
详解vue挂载到dom上会发生什么
2019/01/20 Javascript
[00:19]CN DOTA NEVER DIE!VG夺冠rOtK接受采访
2019/12/23 DOTA
解决Python字典写入文件出行首行有空格的问题
2017/09/27 Python
使用python为mysql实现restful接口
2018/01/05 Python
Python基于生成器迭代实现的八皇后问题示例
2018/05/23 Python
Python模拟百度自动输入搜索功能的实例
2019/02/14 Python
如何使用Python 打印各种三角形
2019/06/28 Python
Python如何基于selenium实现自动登录博客园
2019/12/16 Python
Python中sorted()排序与字母大小写的问题
2020/01/14 Python
Python yield生成器和return对比代码实例
2020/04/20 Python
Python实现读取并写入Excel文件过程解析
2020/05/27 Python
Django与AJAX实现网页动态数据显示的示例代码
2021/02/24 Python
Jack Rogers官网:美国经典的女性鞋靴品牌
2019/09/04 全球购物
业务内勤岗位职责
2014/04/30 职场文书
社区矫正工作方案
2014/06/04 职场文书
先进集体申报材料
2014/12/25 职场文书
2015年药店工作总结
2015/04/20 职场文书