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之有容乃大的list(4)
Sep 28 Python
Python中关键字nonlocal和global的声明与解析
Mar 12 Python
Python使用内置json模块解析json格式数据的方法
Jul 20 Python
Python实现的求解最大公约数算法示例
May 03 Python
使用OpCode绕过Python沙箱的方法详解
Sep 03 Python
18个Python脚本可加速你的编码速度(提示和技巧)
Oct 17 Python
Python坐标线性插值应用实现
Nov 13 Python
如何在windows下安装Pycham2020软件(方法步骤详解)
May 03 Python
Django 解决新建表删除后无法重新创建等问题
May 21 Python
浅谈tensorflow使用张量时的一些注意点tf.concat,tf.reshape,tf.stack
Jun 23 Python
Pytorch学习之torch用法----比较操作(Comparison Ops)
Jun 28 Python
python爬虫之爬取笔趣阁小说
Apr 22 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 socket方式提交的post详解
2008/07/19 PHP
通用PHP动态生成静态HTML网页的代码
2010/03/04 PHP
php中处理mysql_fetch_assoc返回来的数组 不用foreach----echo
2011/05/04 PHP
php中spl_autoload详解
2014/10/17 PHP
浅谈Laravel中的三种中间件的作用
2019/10/13 PHP
prototype 学习笔记整理
2009/07/17 Javascript
JS延迟加载(setTimeout) JS最后加载
2010/07/15 Javascript
过虑特殊字符输入的js代码
2010/08/05 Javascript
javascript静态页面传值的三种方法分享
2013/11/12 Javascript
纯js和css实现渐变色包括静态渐变和动态渐变
2014/05/29 Javascript
简介JavaScript中的setDate()方法的使用
2015/06/11 Javascript
详解JavaScript中常用的函数类型
2015/11/18 Javascript
JavaScript setTimeout使用闭包功能实现定时打印数值
2015/12/18 Javascript
js,jq,css多方面实现简易下拉菜单功能
2017/05/13 Javascript
手把手教你搭建ES6的开发运行环境
2017/07/11 Javascript
在vue中使用G2图表的示例代码
2019/03/19 Javascript
JavaScript this使用方法图解
2020/02/04 Javascript
在Python的Django框架中调用方法和处理无效变量
2015/07/15 Python
在Python的Django框架中使用通用视图的方法
2015/07/21 Python
Python中的延迟绑定原理详解
2019/10/11 Python
Python selenium爬取微博数据代码实例
2020/05/22 Python
Python 利用flask搭建一个共享服务器的步骤
2020/12/05 Python
python UIAutomator2使用超详细教程
2021/02/19 Python
一款利用纯css3实现的360度翻转按钮的实例教程
2014/11/05 HTML / CSS
澳大利亚礼品卡商店:Gift Card Store
2019/06/24 全球购物
Farah官方网站:男士服装及配件
2019/11/01 全球购物
全球最大的瓷器、水晶和银器零售商:Replacements
2020/06/15 全球购物
长青弘远的面试题
2012/06/09 面试题
北大自主招生自荐信
2013/10/19 职场文书
工业设计专业推荐信
2013/10/29 职场文书
现金会计岗位职责
2013/12/05 职场文书
七夕活动策划方案
2014/08/16 职场文书
捐款活动总结
2014/08/27 职场文书
法人委托书范本格式
2014/09/15 职场文书
个人纪律作风整改措施思想汇报
2014/10/12 职场文书
2019年幼儿园管理条例范本!
2019/07/17 职场文书