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使用os模块和fileinput模块来操作文件目录
Jan 19 Python
Python使用PyCrypto实现AES加密功能示例
May 22 Python
Python内置函数——__import__ 的使用方法
Nov 24 Python
Python语言描述最大连续子序列和
Dec 05 Python
django 微信网页授权登陆的实现
Jul 30 Python
Python 中的 import 机制之实现远程导入模块
Oct 29 Python
pycharm通过ssh连接远程服务器教程
Feb 12 Python
Python print不能立即打印的解决方式
Feb 19 Python
python对文件的操作方法汇总
Feb 28 Python
Python configparser模块配置文件过程解析
Mar 03 Python
python 实现网易邮箱邮件阅读和删除的辅助小脚本
Mar 01 Python
python-for x in range的用法(注意要点、细节)
May 10 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
配置Apache2.2+PHP5+CakePHP1.2+MySQL5运行环境
2009/04/25 PHP
使用XDebug调试及单元测试覆盖率分析
2011/01/27 PHP
php简单实现单态设计模式的方法分析
2017/07/28 PHP
Mootools 1.2教程(3) 数组使用简介
2009/09/14 Javascript
判断js中各种数据的类型方法之typeof与0bject.prototype.toString讲解
2013/11/07 Javascript
可自定义速度的js图片无缝滚动示例分享
2014/01/20 Javascript
高性能JavaScript模板引擎实现原理详解
2015/02/05 Javascript
jquery的ajax提交form表单的两种方法小结(推荐)
2016/05/25 Javascript
jQuery实现鼠标滚动图片延迟加载效果附源码下载
2016/06/28 Javascript
Js获取当前日期时间及格式化代码
2016/09/17 Javascript
微信小程序 template模板详解及实例代码
2017/03/09 Javascript
ajax请求+vue.js渲染+页面加载的示例
2018/02/11 Javascript
JS实现移动端触屏拖拽功能
2018/07/31 Javascript
浅谈vue中关于checkbox数据绑定v-model指令的个人理解
2018/11/14 Javascript
layer父页获取弹出层输入框里面的值方法
2019/09/02 Javascript
微信小程序实现二维码签到考勤系统
2020/01/16 Javascript
vue跳转页面的几种方法(推荐)
2020/03/26 Javascript
vue-axios同时请求多个接口 等所有接口全部加载完成再处理操作
2020/11/09 Javascript
Python实现Mysql数据库连接池实例详解
2017/04/11 Python
Linux-ubuntu16.04 Python3.5配置OpenCV3.2的方法
2018/04/02 Python
python矩阵/字典实现最短路径算法
2019/01/17 Python
Python告诉你木马程序的键盘记录原理
2019/02/02 Python
美国照明、家居装饰和家具购物网站:Bellacor
2017/09/20 全球购物
印尼最大的网上书店:Gramedia.com
2018/09/13 全球购物
捷克街头、运动和滑板一站式商店:BoardStar.cz
2019/10/06 全球购物
Roxy俄罗斯官方网站:冲浪和滑雪板的一切
2020/06/20 全球购物
小学开学寄语
2014/01/19 职场文书
详细的大学生创业计划书模板
2014/01/27 职场文书
公司中秋节活动方案
2014/02/12 职场文书
优秀班主任事迹材料
2014/12/16 职场文书
长城英文导游词
2015/01/30 职场文书
电力培训学习心得体会
2016/01/11 职场文书
python 使用Tensorflow训练BP神经网络实现鸢尾花分类
2021/05/12 Python
英镑符号 £
2022/02/17 杂记
Win10 Anaconda安装python-pcl
2022/04/29 Servers
MySQL数据库表约束讲解
2022/06/21 MySQL