迭代器和生成器總結

2022-08-22 14:45:14 字數 3333 閱讀 4575

迭代器:

是乙個抽象的概念,任何物件,如果它的類有 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__方法的物件,就是迭代器,迭代器同時也是乙個可迭代物件

示例**:

class

fibiterator(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:

例如把上面的斐波那契函式改寫成生成式如下:

def

fib(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...