叠代器(Iterable)和for..in..的三種協議
一。叠代器協議
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__返回新的叠代對象。
叠代器(Iterable)和for..in..的三種協議