Python高级话题之一----迭代器(iterator)

简介

首先我们从维基上看对迭代器的定义:迭代器(iterator)有时又称游标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器物件的内容。
在python中,对迭代器的定义是为类似序列的对象提供了一个具有序列特性的接口。它是在python2.2版本中引进进来的。python的迭代器无缝地支持序列对象,而且它还支持非序列类型,包括用户定义的对象。
python中的迭代器用起来很灵巧,你可以迭代不是序列对象但表现出序列行为的对象,例如字典的键、一个文件的行,等等。当你使用循环迭代一个对象条目时,你几乎分辨不出它是迭代器还是序列。你不必去关注这些,因为python让它像一个序列那样操作。

迭代器的作用(优点)

  • PEP234中对迭代器的作用有着明确的记录:
  • 提供了可扩展的迭代器接口;
  • 对字典、列表的迭代带来了性能的提升;
  • 创建真正的迭代接口,而不是原来的随机对象访问;
  • 与所有已经存在的用户定义的类以及扩展的模块序列和映射的对象向后兼容;
  • 迭代非序列对象时,可以创建更加简洁可读的代码;

如何迭代

从根本上说,迭代器就是有一个next()方法的对象,而不是通过索引来计数的。当你或是一个循环机制(例如for语句)需要下一个项时,调用迭代器的next()方法就可以获得它。条目全部取出后,会引发一个StopIteration异常,这并不是表示错误的发生,只是告诉外部的调用者,迭代完成。可以使用iter()函数来创建迭代器,另外还有一种就是自定义类。


方法1.
>>> lst = range(2)
>>> it = iter(lst)
>>> it
<listiterator object at 0x00BB62F0>

方法2.
class A:
    def __iter__(self):
        return self


    def next(self):
        if has_next_value(self):
            return next_value
        else:
            raise StopIteration
class B:
    def __iter__(self):
        return iterator_obj

A,B分别为两种对象模式(都是示例代码)。模式A表示,在A中定义了next方法,因此__iter__简单地返回自身即可。当不存在下一个值时,引发StopIteration异常。模式B表示,它使用了其它的Iterator对象,因此只需要定义__iter__即可,next不需要定义,因为返回的Iterator对象已经含有next方法了。如果是自已实现next方法,那么在返回值之前需要记住当前的状态,以便下一次运行时,可以取下一个值。


迭代器的缺点

迭代器不能回退,只能往前进行迭代。迭代器也不是线程安全的,在多线程环境中对可变集合使用迭代器是一个危险的操作。但如果小心谨慎,或者干脆贯彻函数式思想坚持使用不可变的集合,那这也不是什么大问题


python中内置的迭代数据类型

>>> a = [122, 221, 333]
>>> b = iter(a)
>>> b.next()
122
>>> b.next()
221
>>> b.next()
333
>>> b.next()
Traceback (most recent call last):
  File "", line 1, in ?
StopIteration
字典和文件也是python两个可迭代的数据类型,例子也就省略了。