迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。
对于原生支持随机访问的数据结构(如tuple、list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值)。但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。
另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。
迭代器更大的功劳是提供了一个统一的访问集合的接口,只要定义了_iter_()方法对象,就可以使用迭代器访问。
迭代器有两个基本的方法
next方法:返回迭代器的下一个元素
iter方法:返回迭代器对象本身
看看下面的代码例子
>>> def fab(max):
... n, a, b = 0, 0, 1
... while n < max:
... print b
... a, b = b, a + b
... n = n + 1
...
>>> fab(5)
1
1
2
3
5
>>>
上面代码直接在函数fab(max)中用print打印会导致函数的可复用性变差,因为fab返回None。其他函数无法获得fab函数返回的数列。
>>> def fab(max):
... L = []
... n, a, b = 0, 0, 1
... while n < max:
... L.append(b)
... a, b = b, a + b
... n = n + 1
... return L
...
>>> fab(5)
[1, 1, 2, 3, 5]
>>>
上面代码满足了可复用性的需求,但是占用了内存空间,最好不要如此。
>>> class Fab(object):
... def __init__(self, max):
... self.max = max
... self.n, self.a, self.b = 0, 0, 1
... def __iter__(self):
... return self
... def next(self):
... if self.n < self.max:
... r = self.b
... self.a, self.b = self.b, self.a + self.b
... self.n = self.n + 1
... return r
... raise StopIteration()
...
>>> for num in Fab(5):
... print num
...
1
1
2
3
5
>>>
上面代码在每次迭代中返回一个元素,因此可以使用迭代器来解决复用可占空间的问题。
注意,迭代器实现了_iter_方法,这个方法实际上返回迭代器本身。在很多情况下,_iter_方法会放到其他的for循环中使用的对象中。这样一来,程序就能返回所需的迭代器。此外,推荐使迭代器实现它自己的_iter_方法,然后就能直接在for循环中使用迭代其本身了。
内建函数iter可以从迭代的对象中获得迭代器。如下所示:
>>> it = iter([1, 2, 3])
>>> it.next()
1
>>> it.next()
2
除此之外,它也可以从函数或者其他可调用对象中获取可迭代对象(详见python库参考http://docs.python.org/lib/获取更多信息