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中splitlines()方法的使用简介
May 20 Python
Python中的zipfile模块使用详解
Jun 25 Python
python实现JAVA源代码从ANSI到UTF-8的批量转换方法
Aug 10 Python
python将ansible配置转为json格式实例代码
May 15 Python
python实现关键词提取的示例讲解
Apr 28 Python
python pandas读取csv后,获取列标签的方法
Nov 12 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
Jun 04 Python
python matplotlib如何给图中的点加标签
Nov 14 Python
TensorFlow实现指数衰减学习率的方法
Feb 05 Python
在python3中使用shuffle函数要注意的地方
Feb 28 Python
Python爬虫如何破解JS加密的Cookie
Nov 19 Python
浅谈Python数学建模之整数规划
Jun 23 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/06/30 PHP
Smarty中常用变量操作符汇总
2014/10/27 PHP
php判断linux下程序问题实例
2015/07/09 PHP
JS 图片缩放效果代码
2010/06/09 Javascript
web网页按比例显示图片实现原理及js代码
2013/08/09 Javascript
JavaScript 表单处理实现代码
2015/04/13 Javascript
js精美的幻灯片画集特效代码分享
2015/08/29 Javascript
javascript实现简单加载随机色方块
2015/12/25 Javascript
深入理解Javascript中的自执行匿名函数
2016/06/03 Javascript
jQuery中的select操作详解
2016/11/29 Javascript
JS中事件冒泡和事件捕获介绍
2016/12/13 Javascript
HTML5 js实现拖拉上传文件功能
2020/11/20 Javascript
Node.js对MongoDB数据库实现模糊查询的方法
2017/05/03 Javascript
JavaScript中document.referrer的用法详解
2017/07/04 Javascript
认识less和webstrom的less配置方法
2017/08/02 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
2017/10/14 jQuery
详解Vue This$Store总结
2018/12/17 Javascript
jQuery实现简单QQ聊天框
2020/08/27 jQuery
vue+elementUI中表格高亮或字体颜色改变操作
2020/11/02 Javascript
Python实现求笛卡尔乘积的方法
2017/09/16 Python
对Python中Iterator和Iterable的区别详解
2018/10/18 Python
Python List列表对象内置方法实例详解
2019/10/22 Python
Pycharm小白级简单使用教程
2020/01/08 Python
Python基础之列表常见操作经典实例详解
2020/02/26 Python
Python三维绘图之Matplotlib库的使用方法
2020/09/20 Python
英国可持续奢侈品包包品牌:Elvis & Kresse
2018/08/05 全球购物
咖啡书吧创业计划书
2014/01/13 职场文书
财产公证书样本
2014/04/04 职场文书
全国税务系统先进集体事迹材料
2014/05/19 职场文书
国庆促销活动总结
2014/08/29 职场文书
英文升职感谢信
2015/01/23 职场文书
2015年感恩母亲节的演讲稿
2015/03/18 职场文书
2015年中秋节主持词
2015/07/30 职场文书
国际贸易实训总结
2015/08/03 职场文书
《惊弓之鸟》教学反思
2016/02/20 职场文书
SQL Server的存储过程与触发器以及系统函数和自定义函数
2022/04/10 SQL Server