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 相关文章推荐
Python3基础之条件与循环控制实例解析
Aug 13 Python
Python中的super用法详解
May 28 Python
Python 编码处理-str与Unicode的区别
Sep 06 Python
利用Python操作消息队列RabbitMQ的方法教程
Jul 19 Python
Python爬取当当、京东、亚马逊图书信息代码实例
Dec 09 Python
Python使用 Beanstalkd 做异步任务处理的方法
Apr 24 Python
对python抓取需要登录网站数据的方法详解
May 21 Python
Python爬虫设置代理IP(图文)
Dec 23 Python
Django组件cookie与session的具体使用
Jun 05 Python
python 单线程和异步协程工作方式解析
Sep 28 Python
Python如何使用input函数获取输入
Aug 06 Python
用 Django 开发一个 Python Web API的方法步骤
Dec 03 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.ini中的php-5.2.0配置指令详解
2008/03/27 PHP
phpMyAdmin 链接表的附加功能尚未激活的问题
2010/08/01 PHP
php中检查文件或目录是否存在的代码小结
2012/10/22 PHP
php保存二进制原始数据为图片的程序代码
2014/10/14 PHP
PHP实现对xml进行简单的增删改查(CRUD)操作示例
2017/05/19 PHP
js宝典学习笔记(上)
2007/01/10 Javascript
jQuery截取指定长度字符串代码
2014/08/21 Javascript
javascript文本框内输入文字倒计数的方法
2015/02/24 Javascript
微信小程序开发之实现选项卡(窗口顶部TabBar)页面切换
2016/11/25 Javascript
JS实现动态添加DOM节点和事件的方法示例
2017/04/28 Javascript
响应式框架Bootstrap栅格系统的实例
2017/12/19 Javascript
Vue底层实现原理总结
2018/02/17 Javascript
JS算法题之查找数字在数组中的索引位置
2019/05/15 Javascript
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
2019/06/10 Javascript
vue + elementUI实现省市县三级联动的方法示例
2019/10/29 Javascript
Vue组件间数据传递的方式(3种)
2020/07/13 Javascript
Pycharm设置去除显示的波浪线方法
2018/10/28 Python
python matplotlib库直方图绘制详解
2019/08/10 Python
Python API自动化框架总结
2019/11/12 Python
从numpy数组中取出满足条件的元素示例
2019/11/26 Python
简单了解python装饰器原理及使用方法
2019/12/18 Python
python圣诞树编写实例详解
2020/02/13 Python
python使用matplotlib:subplot绘制多个子图的示例
2020/09/24 Python
运行Python编写的程序方法实例
2020/10/21 Python
CSS3教程(2):网页边框半径和网页圆角
2009/04/02 HTML / CSS
英国骑行、跑步、游泳、铁人三项运动装备专卖店:Wiggle
2016/08/23 全球购物
英国天然有机美容护肤品:Neal’s Yard Remedies
2018/05/05 全球购物
SmartBuyGlasses德国:购买太阳镜和眼镜
2019/08/20 全球购物
学习自我鉴定
2014/02/01 职场文书
保证书格式范文
2014/04/28 职场文书
水电维修专业推荐信
2014/09/06 职场文书
2016新年年会主持词
2015/07/06 职场文书
军训通讯稿范文
2015/07/18 职场文书
党风廉政承诺书2016
2016/03/25 职场文书
2019年中,最受大众欢迎的6本新书
2019/08/07 职场文书
SSM项目使用拦截器实现登录验证功能
2022/01/22 Java/Android