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实现把json格式转换成文本或sql文件
Jul 10 Python
简单谈谈python的反射机制
Jun 28 Python
python实现换位加密算法的示例
Oct 14 Python
python 利用for循环 保存多个图像或者文件的实例
Nov 09 Python
Python数据集切分实例
Dec 08 Python
Python图像处理之图像的缩放、旋转与翻转实现方法示例
Jan 04 Python
pandas dataframe添加表格框线输出的方法
Feb 08 Python
Tensorflow累加的实现案例
Feb 05 Python
Python中文分词库jieba,pkusegwg性能准确度比较
Feb 11 Python
django admin后管定制-显示字段的实例
Mar 11 Python
Django models文件模型变更错误解决
May 11 Python
python读取excel进行遍历/xlrd模块操作
Jul 12 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中抽象类和抽象方法概念与用法分析
2016/05/24 PHP
Yii2组件之多图上传插件FileInput的详细使用教程
2016/06/20 PHP
PHPCMS忘记后台密码的解决办法
2016/10/30 PHP
详解PHP处理密码的几种方式
2016/11/30 PHP
浅谈php的TS和NTS的区别
2019/03/13 PHP
Javascript 文件夹选择框的两种解决方案
2009/07/01 Javascript
JS 时间显示效果代码
2009/08/23 Javascript
百度Popup.js弹出框进化版 拖拽小框架发布 兼容IE6/7/8,Firefox,Chrome
2010/04/13 Javascript
javascript中使用replaceAll()函数实现字符替换的方法
2010/12/25 Javascript
javascript 利用Image对象实现的埋点(某处的点击数)统计
2012/12/28 Javascript
Javascript 绘制 sin 曲线过程附图
2014/08/21 Javascript
Javascript 赋值机制详解
2014/11/23 Javascript
Bootstrap每天必学之标签与徽章
2015/11/27 Javascript
谈谈我对JavaScript中typeof和instanceof的深入理解
2015/12/25 Javascript
浅谈Angular HttpClient简单入门
2018/05/04 Javascript
详解小程序横屏方案对比
2020/06/28 Javascript
Scrapy的简单使用教程
2017/10/24 Python
基于并发服务器几种实现方法(总结)
2017/12/29 Python
对numpy和pandas中数组的合并和拆分详解
2018/04/11 Python
Python实现判断一行代码是否为注释的方法
2018/05/23 Python
更换Django默认的模板引擎为jinja2的实现方法
2018/05/28 Python
pandas DataFrame实现几列数据合并成为新的一列方法
2018/06/08 Python
numpy和pandas中数组的合并、拉直和重塑实例
2019/06/28 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
python的Jenkins接口调用方式
2020/05/12 Python
使用ITK-SNAP进行抠图操作并保存mask的实例
2020/07/01 Python
Python爬虫实例——爬取美团美食数据
2020/07/15 Python
浅析css3中matrix函数的使用
2016/06/06 HTML / CSS
俄罗斯外国汽车和国产汽车配件网上商店:Движком
2020/04/19 全球购物
局部内部类是否可以访问非final变量?
2013/04/20 面试题
医院节能减排方案
2014/06/13 职场文书
干部作风建设年活动剖析材料
2014/10/23 职场文书
2015年建党94周年演讲稿
2015/03/19 职场文书
推荐信范文大全
2015/03/27 职场文书
学习杨善洲同志先进事迹心得体会
2016/01/23 职场文书
2016计算机专业毕业生自荐信
2016/01/28 职场文书