Python从入门到放弃之迭代器

迭代器是Python2.1中新加入的接口(PEP 234),说明以下:python

The iterator provides a 'get next value' operation that
produces the next item in the sequence each time it is called, raising an exception when no more items are available.

说到迭代器,就不得不提迭代器对象(Iterator)和可迭代对象(Iterable)。
接下来将分别介绍这两种对象。python2.7

可迭代对象

可迭代对象(Iterable)能够是任何对象,只要该对象拥有__iter__方法。该方法会返回一个迭代对象(Iterator)。
咱们经常使用到的如listtupledictsetstr等都是Iterableide

接下来用list作一些验证。post

#!/usr/bin/env python2.7
"""以后全部代码只保留必要部分"""
from collections import Iterator, Iterable

hasattr([], '__iter__')      # True
isinstance([], Iterable)     # True
type(iter([]))               # <type 'list_iterator'>

 注: iter()是内建方法,可将Iterable转为Iterator
iter()只接受Iterable对象做为参数,若是不是则会抛出TypeError错误。code

能够看出,list拥有__iter__方法, 它是一个可迭代对象,当对list使用iter()方法后,会返回一个Iterator对象。对象

a = [1, 2, 3, 4]
for i in a:
    print i

# 实际上内部执行
_iter = iter(a)
while True:
    try:
        a = _iter.next()
        print a
    except StopIteration:
        break

迭代器对象

迭代器对象则是在可迭代对象的基础上多实现一个next()方法。接口

class Too(object):
    def __init__(self):
        self.n = 5

    def __iter__(self):
        return self

    def next(self):
        if self.n < 1:
            self.n = 5
            raise StopIteration
        val = self.n
        self.n -= 1
        return val

t = Too(5)

isinstance(t, Iterable)      # True
isinstance(t, Iterator)      # True

next(t)                      # 5
next(t)                      # 4
next(t)                      # 3
next(t)                      # 2
next(t)                      # 1
next(t)                      # StopIteration

如上则是实现一个简单的迭代器。get

能够看出,只有当使用next()方法时,迭代器才会返回一个值,并且每次返回的都是与以前一次相对应的值,如第一次返回的是5,第二次返回的是4,而不是3或者2或者别的什么数字。generator

这是由于迭代器内部有一种相似状态机的机制,会保存每次的next()调用后的状态,因此每次调用总会返回正确的结果。it

总结

迭代器对象与可迭代对象的关系总结起来就是一句话,迭代器对象必定是可迭代对象,可迭代对象不必定是迭代器对象。

参考文章:
StackOverflow
nvie.com
generators-uk

相关文章
相关标签/搜索