前言:算法
以前在迭代器、可迭代對象這一部分一直有些混淆,結合一些資料,表達我對這些概念的理解,未必都對,可是適合剛開始入手的朋友們從零開始理解spa
開門見山首先介紹可迭代對象和迭代器的通俗理解code
迭代器就是能被next()調用獲得下一次迭代值的對象,迭代器不直接保存迭代的序列值,而保存獲得下一次迭代值的算法對象
可迭代對象就是能被iter()方法調用獲得迭代器的對象,能進行for循環的必須是可迭代對象blog
for循環的底層實現原理:it
如下是一個for循環的格式io
for i in 可迭代對象: 循環體
實質是調用內建方法iter()獲得迭代器對象,而後經過每次調用next(迭代器)獲得i的迭代值for循環
例如如下的代碼:class
for i in x: print(i)
徹底能夠改寫爲:變量
iterator = iter(x) while True: i = next(iterator) print(i)
從嚴格或者底層原理來講
迭代器或迭代器對象:實現了__next__()魔法方法的(類所實例化的)對象,該方法返回迭代器下一個值(保存獲得下一個迭代值的算法)
可迭代對象:實現了__iter__()魔法方法的(類所實例化的)對象,該方法返回一個迭代器對象
實際上,next和iter是對__next__和__iter__的進一步封裝或者說next和iter在執行的時候又分別調用了內部的__next__和__iter__從而實現迭代器和可迭代對象的特性和功能
綜上,咱們能夠理解for循環、可迭代對象、迭代器三者的聯繫:
for循環只能對可迭代對象進行,可迭代對象又須要迭代器的實現
由此,咱們能夠自定義實現迭代器和可迭代迭代對象,從而實現自定義的for循環效果
示例:
經過迭代器和可迭代對象實現菲波那切數列
分別定義迭代器和可迭代對象所屬的類:
class Fib:
'''定義可迭代對象所屬類''' def __init__(self,num): #num表示該數列的長度 self.a = 1 self.b = 2
self.current=self.a
self.num = num def __iter__(self): return FebIterator(self) class FibIterator(self):
'''定義迭代器類''' def __init__(self,source): self.source = source def __next__(self):
if(self.num-1>=0):
self.num = self.num-1 self.current = self.a self.a = self.b self.b = self.b+self.current #以上兩步賦值操做可省略中間變量直接寫爲self.a,self.b = self.b,self.a+self,b
return self.curent
else: raise StopIteration
經過調用這兩個類的實例化對象,能夠實現循環打印斐波那契數列
fib = Fib()
for i in fib: print(i)
實際上,爲了簡化和方便,徹底能夠在一個類中同時實現__iter__()和__next__()方法,也即該類實例化的對象既是一個可迭代對象也是迭代器,代碼以下:
class Fib: def __init__(): self.a = 1 self.b = 2
sele.current = self.a def __iter__(self): return self def __next__():
if(self.num-1>=0):
self.num = self.num-1 self.current = self.a self.a = self.b self.b = self.b+self.current #以上兩步賦值操做可省略中間變量直接寫爲self.a,self.b = self.b,self.a+self,b
return self.curent
else: raise StopIteration
其使用方法和以前沒有區別,反而更加簡便,前提是對迭代器和可迭代對象有清晰的理解和認識,不然會對兩者概念產生混淆