-----------------------------------------------------------------------------前言----------------------------------------------------------------------------------

  • python中的for循环可以在各种容器container上遍历所有可用元素。
  • 一个类里面,如果实现了  __iter__ 这个函数, 那这个类就是 “iterable”。
  • 如果它还实现了 next ( self ) ,那它就称为 iterator。

------------------------------------------------------------------------------正文-------------------------------------------------------------------------------------

我们都知道,Python有for循环。我们可以用for循环在各种容器container上遍历其所有可用的元素。
比如:
在列表(list)上遍历:

  1. >>> for i in [1, 2, 3]:
  2. ... print i
  3. ...
  4. 1
  5. 2
  6. 3

在字符串(string)上遍历:

  1. >>> for i in 'iter':
  2. ... print i
  3. ...
  4. i
  5. t
  6. e
  7. r

除此之外,还可以在元组(tuple),字典(dictionary)和文件(file)上遍历。这些遍历操作涉及到
同一个概念,那就是Python的迭代器(iterator)。维基百科中是这样定义迭代器的: 在面向对象的
程序设计语言
中,迭代器(iterator)是一个对象,这个对象可以让程序员在容器(container)上遍历。
Python中的迭代器(iterator)则是实现了迭代协议的对象。迭代协议由下面的两种方法组成,实现了
这两种方法就是实现了迭代协议。

1、__iter__(): 返回iterator对象本身。
2、next(): 每当next()方法被调用时,返回下一个值直到StopIteration的异常被抛出【1】

在Python里,iterator主要用于for循环。首先,我们来看一段代码:

  1. >>> lst = ['a', 'b', 'c', 'd', 'e']
  2. >>> for i in lst:
  3. ... print i
  4. ...
  5. a
  6. b
  7. c
  8. d
  9. e
  10. >>> lst_iter = iter(lst)
  11. >>> for i in lst_iter:
  12. ... print i
  13. ...
  14. a
  15. b
  16. c
  17. d
  18. e
  19. >>> type(lst_iter)
  20. <type 'listiterator'>

对于container类型【2】(列表是典型的container),可以直接用于for循环进行遍历。而将列表转化成
迭代器(iterator)进行遍历,效果似乎一样。
为什么两种方法都可以呢?Python到底是怎样遍历一个container的呢?前面提到Python中的迭代器
(iterator)实现两种方法分别是__iter__()和next(),Python正是通过调用这两种方法来实现遍历的。
首先,当Python在执行for循环时,会先调用container的__iter__()方法【3】 来获得container的迭代器
(iterator),其实就是将container转化成迭代器(iterator)。然后它会重复调用迭代器(iterator)的
next()方法,直到迭代器(iterator)抛出StopIteration的异常。一旦这个异常抛出,for循环就结束了。
看下面的代码,和上面的两种方法同样的结果。

  1. >>> _lst_iter = lst.__iter__() # 返回lst的iterator
  2. >>> for i in _lst_iter:
  3. ... print i
  4. ...
  5. a
  6. b
  7. c
  8. d
  9. e
  10. >>> type(_lst_iter)
    <type 'listiterator'>

在Python的内置数据类型中,list,tuple,dictionary,set都是container且都可以直接用于for循环。

  1. >>> s = {'a', 'b', 'c'}   # set
  2. >>> s
  3. set(['a', 'c', 'b'])
  4. >>> s.__iter__()
  5. <setiterator object at 0x7fac6c6f3280>
  6. >>> t = ('a', 'b', 'c')   # tuple
  7. >>> t
  8. ('a', 'b', 'c')
  9. >>> t.__iter__()
  10. <tupleiterator object at 0x7fac6c6fb490>
  11. >>> d = {1: 'a', 2: 'b', 3: 'c'}   # dict
  12. >>> d
  13. {1: 'a', 2: 'b', 3: 'c'}
  14. >>> d.__iter__()
  15. <dictionary-keyiterator object at 0x7fac6c6def70>
  16. >>>

上面的代码可以看出,这四种container都有__iter__(),一般把这种拥有__iter__()方法的container
叫做iterable。但是要注意,container和iterator的__iter__()方法虽然同名,但是返回的对象是不一样
的。container的__iter__()返回的是一个iterator对象,而iterator的__iter__()返回的是它自己,即
iterator对象本身。以一个list为例:

  1. >>> a = [1, 2, 3]     # list container
  2. >>> b = a.__iter__()  # listiterator
  3. >>> a is a.__iter__()
  4. False
  5. >>> b is b.__iter__()
  6. True
  7. >>>

除了Python内置的iterator,用户也可以通过实现迭代协议定义自己的iterator。自定义iterator,很显然是要实现
__iter__()和next()方法。例如我们定义一个偶数迭代器。

  1. class EvenIterators(object):
  2. def __init__(self, n):
  3. self.stop = n
  4. self.value = -2
  5. def __iter__(self):
  6. return self
  7. def next(self):
  8. if self.value + 2 > self.stop:
  9. raise StopIteration
  10. self.value += 2
  11. return self.value
  12. >>> from iterator import EvenIterators
  13. >>> even_iter = EvenIterators(5)
  14. >>> even_iter.next()
  15. 0
  16. >>> even_iter.next()
  17. 2
  18. >>> even_iter.next()
  19. 4
  20. >>> even_iter.next()
  21. Traceback (most recent call last):
  22. File "<stdin>", line 1, in <module>
  23. File "iterator.py", line 18, in next
  24. raise StopIteration
  25. StopIteration
  26. >>> for e in EvenIterators(5):
  27. ... print e
  28. ...
  29. 0
  30. 2
  31. 4
  32. >>> list(EvenIterators(9))
  33. [0, 2, 4, 6, 8]
  34. >>>

上面的EvenIterators类实现了一个偶数迭代器。从这个例子我们可以看出,只要我们实现了迭代协议,即
方法__iter__()和next(),我们就实现了iterator。

注:

【1】当所有可用的值都被遍历后,StopIteration才会被抛出。
【2】In computer science, a container is a class, a data structure, or an abstract data type (ADT) whose instances are
        collections of other objects. In other words; they are used for storing objects in an organized way following specific
        access rules. The size of the container depends on the number of the objects (elements) it contains. (Wikipedia)
【3】如果一个container是iterable,那么这个container拥有__iter__()方法,此方法将转化container成iterator。

-------------------------------------------------------------------------------------------后记---------------------------------------------------------------------------

python——iterator迭代器|iterator详解——20140918|的更多相关文章

  1. python操作redis用法详解

    python操作redis用法详解 转载地址 1.redis连接 redis提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用 ...

  2. python之OS模块详解

    python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...

  3. python之sys模块详解

    python之sys模块详解 sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传 ...

  4. python中threading模块详解(一)

    python中threading模块详解(一) 来源 http://blog.chinaunix.net/uid-27571599-id-3484048.html threading提供了一个比thr ...

  5. Python数据类型及其方法详解

    Python数据类型及其方法详解 我们在学习编程语言的时候,都会遇到数据类型,这种看着很基础也不显眼的东西,却是很重要,本文介绍了python的数据类型,并就每种数据类型的方法作出了详细的描述,可供知 ...

  6. python引用和对象详解

    python引用和对象详解 @[马克飞象] python中变量名和对象是分离的 例子 1: a = 1 这是一个简单的赋值语句,整数 1 为一个对象,a 是一个引用,利用赋值语句,引用a指向了对象1. ...

  7. Python中time模块详解

    Python中time模块详解 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. ...

  8. Python 列表(List)操作方法详解

    Python 列表(List)操作方法详解 这篇文章主要介绍了Python中列表(List)的详解操作方法,包含创建.访问.更新.删除.其它操作等,需要的朋友可以参考下   列表是Python中最基本 ...

  9. Python模块调用方式详解

    Python模块调用方式详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其 ...

  10. python之模块datetime详解

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python之模块datetime详解 import datetime #data=datetime.dat ...

随机推荐

  1. 洛谷 P1463 [SDOI2005]反素数ant && codevs2912反素数

    题目描述 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4. 如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例如,整数1,2,4,6 ...

  2. ABC103

    Wow今天听同学说了这个网站,做了一次比赛的题目,只有四道题. A.三个数a,b,c,找两个最小的差相加,显然是中间数与另外两个数的差,也就是最大值减最小值了 B.两个字符串,判断能否通过对一个进行每 ...

  3. css 实现高斯模糊

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 设置JPA的Query返回Map对象

    说明正常执行jpa查询的时候需要传一个对应实体进行映射返回的数据,这样有时候如果一个sql是复合sql关联很多表,就需要新建实体有点麻烦,通过下面方式就能将返回结果映射成map.这样就能随意获取返回结 ...

  5. css之其它技巧和经验列表

    其它技巧和经验列表(*以下实例默认运行环境都为Standard mode): 如何让层在falsh上显示? 方法: ``` 设置flash的wmode值为transparent或opaque ``` ...

  6. python--io

    import io # io模块里面主要使用StringIo和BytesIo # StringIo f = io.StringIO() # 像使用open函数创建文件一样,生成一个句柄 # 可以直接向 ...

  7. 向PE文件中空白处添加代码

    // mem.cpp : 定义控制台应用程序的入口点. //PE文件从文件加载到内存,再从内存读取,然后存盘到文件 #include "stdafx.h" #include < ...

  8. js-限制参与活动的范围(微信H5活动)

    近期接到大连某个项目,一个H5的活动,其中有一个需求就是:这个活动的参与者仅限大连地区的用户 所以参考了微信API 得出的操作结果为: wx.ready(function() { wx.getLoca ...

  9. (4)C#变量,常量,数据类型,转义字符,数据类型转换

    一.变量 程序运行期间能够被改变的量称为变量. 变量名称要用小写字母开头,避免用下划线开头. 如果包含多个单词,从第二个单词开始首字母都要大写. 定义并初始化 double pi = 3.14 二.常 ...

  10. Codevs1026 SEARCH(逃跑的拉尔夫 )(BFS)

    SEARCH 时间限制: 1 Sec  内存限制: 128 MB提交: 11  解决: 4[提交][状态][讨论版] 题目描述 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警 ...