一。迭代器协议
1. 迭代器协议:对象需要提供next方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代
2. 可跌达对象:实现了迭代器协议的对象
3. 协议是一种约定,可迭代对象实现迭代器协议,在Python中,迭代是通过for ... in
来完成的
二。简单迭代器
以斐波那契数列为例,写一个简单的迭代器
>>> from collections import Iterable >>> class Fib: ... def __init__(self): ... self.a,self.b = 0,1 ... def __iter__(self): ... return self ... def next(self): ... self.a,self.b = self.b,self.a + self.b ... if self.a > 100: ... raise StopIteration() ... return self.a ... >>> a = Fib() >>> for n in a: ... print n ... 1 1 2 3 5 8 13 21 34 55 89 >>> isinstance(a,Iterable) True >>>
Fib既是一个可迭代对象(因为它实现了__iter__
方法),又是一个迭代器(因为实现了__next__
方法)
再简化一下,不用for....in....
>>> a = Fib() >>> it = iter(a) >>> next(it) 1 >>> next(it) 1 >>> next(it) 2 >>> next(it) 3 >>>
一个迭代器只迭代一次,重复跌代要获得新的迭代器。
三。for...in... 协议
1. 协议A: __iter__ + next
这是迭代器的协议,和上面说的一样,for..in.. 先调用iter(a) 让a的__iter__返回一个迭代器,然后循环这个迭代器的next方法直到没有下一个元素异常退出。
for...in... 首先执行跌达器,比如存在跌达和__getitem__就会以跌达器遍历.
2. 协议B: __getitem__
>>> class B: ... def __getitem__(self,n): ... print n ... time.sleep(2) ... return ‘a‘ ... >>> b = B() >>> for x in b: ... print x ... 0 a 1 a 2 a 3 a 4
n 一直循环的增长,直到有异常此循环才退出,一般作为下标索引遍历
>>> class B: ... def __init__(self): ... self.l = [‘a‘,‘b‘,‘c‘,‘d‘,‘e‘] ... def __getitem__(self,n): ... return self.l[n] ... >>> b = B() >>> for x in b: ... print x ... a b c d e >>>
3. 协议C: yield关键字
>>> def c(): ... yield ‘a‘ ... yield ‘b‘ ... yield ‘c‘ ... yield ‘d‘ ... >>> c1 = c() >>> print next(c1),next(c1),next(c1),next(c1),next(c1) a b c d Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>>
这是生成器(generator),是可迭代对象,不是一次性列出结果,用到了才按照某种规则得出结果,占用内存很少,用for...in...时不断循环调用 next() 方法,每次 next() 后 yield 返回一个值并挂起,到下次 next() 从上次挂起的 yield 接着执行,yield 和 return 一样返回值,生成器只迭代一次,因为没有__iter__返回新的迭代对象。
时间: 2024-10-23 00:07:56