迭代器:
是乙個抽象的概念,任何物件,如果它的類有 next 方法和 iter 方法返回自己本身,對於 string、list、dict、tuple 等這類容器物件,使用 for 迴圈遍歷是很方便的。在後台 for 語句對容器物件呼叫 iter()函式,iter()是 python 的內建函式。iter()會返回乙個定義了 next()方法的迭代器物件,它在容器中逐個訪問容器內元素,next()也是 python 的內建函式。在沒有後續元素時,next()會丟擲乙個 stopiteration 異常。
關於iter()和next():
1、iter(iterable)函式是把可迭代物件的迭代器取出來,內部是呼叫可迭代物件的__iter__方法,來取得迭代器的
2、next(iterator)函式是通過迭代器取得下乙個位置的值,內部是呼叫迭代器物件的__next__方法,來取得下乙個位置的值
注意:
當我們已經迭代完最後乙個資料之後,再次呼叫next()函式會丟擲stopiteration的異常,來告訴我們所有資料都已迭代完成,不用再執行next()函式了。
所以:我們要想構造乙個迭代器,就要實現它的__next__方法。但這還不夠,python要求迭代器本身也是可迭代的,所以我們還要為迭代器實現__iter__方法,而__iter__方法要返回乙個迭代器,迭代器自身正是乙個迭代器,所以迭代器的__iter__方法返回自身即可。
結論:
乙個實現了__iter__方法和__next__方法的物件,就是迭代器,迭代器同時也是乙個可迭代物件
示例**:
classfibiterator(object):
"""斐波那契數列迭代器
"""def
__init__
(self, n):
#記錄生成fibonacci的數列的個數
self.n =n
#記錄當前遍歷的下標
self.current_index =0
#記錄fibonacci數列前面的兩個值
self.num1 =0
self.num2 = 1
def__next__
(self):
"""被next()函式呼叫來獲取下乙個數
"""if self.current_index num =self.num1
self.num1, self.num2 = self.num2, self.num1 +self.num2
self.current_index += 1
return
num
else
:
raise
stopiteration
def__iter__
(self):
"""迭代器的__iter__返回自身即可
"""return
self
if__name__ == '
__main__':
fib = fibiterator(10)
for num in
fib:
print("
", num, end="")
# 執行結果: 0 1 1 2 3 5 8 13 21 34
生成器(generator):
是建立迭代器的簡單而強大的工具。生成器是一種特殊的迭代器,它比迭代器寫起來更加優雅,它們寫起來就像是正規的函式,只是在需要返回資料的時候使用 yield 語句。每次 next()被呼叫時,生成器會返回它脫離的位置(它記憶語句最後一次執行的位置和所有的資料值)
最簡單的生成器就是把乙個列表生成式的[ ]改成( )
例如:g = (x*2 for x in rang(5)),就是乙個生成器
另外一種生成器的建立方法就是這乙個函式裡面加yield:
例如把上面的斐波那契函式改寫成生成式如下:
deffib(n):
current_index =0
num1, num2 = 0, 1
while current_index #print(num1) # 列印斐波那契數列
"""1. 假如函式中有yield,則不再是函式,而是生成器
2. yield 會產生乙個斷點
3. 假如yield後面緊接著乙個資料,就會把資料返回,
作為next()函式或者for ...in...迭代出的下乙個值
"""yield
num1
num1, num2 = num2, num1 +num2
current_index += 1
if__name__ == '
__main__':
#假如函式中有yield,則不再是函式,而是乙個生成器
gen = fib(10)
#生成器是一種特殊的迭代器
for num in
gen:
print(num)
# 執行結果: 0 1 1 2 3 5 8 13 21 34
通過**可以很直**出生成器更優雅更省**
yield其實就是儲存當前程式執行狀態。你用 for 迴圈的時候,每次取乙個元素的時候就會計算一次。用 yield 的函式叫 generator,和 iterator 一樣,它的好處是不用一次計算所有元素,而是用一次算一次,可以節省很多空間。generator每次計算需要上一次計算結果,所以用 yield,否則一 return,上次計算結果就沒了,簡單來說乙個函式裡面加了yield就是生成器。
還有我們除了可以使用next()函式來喚醒生成器繼續執行外,還可以使用send()函式來喚醒執行。使用send()函式的乙個好處是可以在喚醒的同時向斷點處傳入乙個附加資料。
總結:
1、使用了yield關鍵字的函式不再是函式,而是生成器。(使用了yield的函式就是生成器)
2、yield關鍵字有兩點作用:
儲存當前執行狀態(斷點),然後暫停執行,即將生成器(函式)掛起
將yield關鍵字後面表示式的值作為返回值返回,此時可以理解為起到了return的作用
3、可以使用next()函式讓生成器從斷點處繼續執行,即喚醒生成器(函式)
區別:
生成器能做到迭代器能做的所有事,而且因為自動建立了 iter()和 next()方法,生成器顯得特別簡潔,而且生成器也是高效的,使用生成器表示式取代列表解析可以同時節省記憶體。除了建立和儲存程式狀態的自動方法,當發生器終結時,還會自動丟擲 stopiteration 異常。
生成器和迭代器
可以直接作用於for迴圈的物件稱為可迭代物件 iterable.可以用isinstance 判斷乙個物件是否是iterable物件。isinstance iterable true isinstance iterable true isinstance 235,iterable false 而生成器...
迭代器和生成器
1 迭代器的概念 print dir 告訴我列表的所有用法 有雙下劃線的所有方法叫做雙下方法,是c語言已經寫好的方法。你可以用不止一種方法呼叫它。列表的用法變集合 set dir 求交集 set dir set dir set dir 求列表,字典,字串它們的用法的交集 他們共同的用法 iterab...
生成器和迭代器
1.iterator 迭代器 舉例 我們對list使用for for i in 1,2,3,4 print i 12 34對string物件使用for for ch in python print ch py thon對字典物件使用for for k in print k yx對檔案使用for fo...