python 生成器和迭代器

一、列表是寫死的,固定的。html

a=[0,1,2,3,4,5,6,7,8,9]python

print(a)算法

二、列表生成式會使代碼更加簡潔app

a=[]函數

for i in range(10):oop

a.append(i*3)spa

print(a)htm

三、列表與列表生成式的運行結果以下:對象

列表運行結果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]blog

列表生成式運行結果:[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]

什麼是生成器

經過列表生成式,咱們能夠直接建立一個列表。可是,受到內存限制,列表容量確定是有限的。並且,建立一個包含100萬個元素的列表,不只佔用很大的存儲空間,若是咱們僅僅須要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。

因此,若是列表元素能夠按照某種算法推算出來,那咱們是否能夠在循環的過程當中不斷推算出後續的元素呢?這樣就沒必要建立完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱爲生成器:generator。

如何建立一個生成器

在一個通常函數中使用yield關鍵字,能夠實現一個最簡單的生成器,此時這個函數變成一個生成器函數。yield與return返回相同的值,區別在於return返回後,函數狀態終止,而yield會保存當前函數的執行狀態,在返回後,函數又回到以前保存的狀態繼續執行。

生成器函數與通常函數的不一樣

生成器函數包含一個或者多個yield當調用生成器函數時,函數將返回一個對象,可是不會馬上向下執行像__iter__()和__next__()方法等是自動實現的,因此咱們能夠經過next()方法對對象進行迭代一旦函數被yield,函數會暫停,控制權返回調用者局部變量和它們的狀態會被保存,直到下一次調用函數終止的時候,StopIteraion會被自動拋出生成器如何節省資源?

只記住當前位置,生成器只保留一個值,next以後上一個值就沒有了

只有一個next方法,

#b#__next__()

著名的斐波那契數列

著名的斐波那契數列,除第一個和第二個數外,任意一個數均可由前兩個數相加獲得:

1,1,2,3,5,8,13,21,34,...

斐波那契數列用列表生成式寫不出來,可是,用函數把它打印出來卻很容易:

def fib(max): n,a,b=0,0,1 while n<max: print(b) a, b = b, a+b n=n+1 return 'done'f=fib(10)運行結果:

1

1

2

3

5

8

13

21

34

55

想要使它變爲生成器,只須要將print(b),改成yiled b便可

def fib(max): n,a,b=0,0,1 while n<max: # print(b) yield b a, b = b, a+b #a = b a = 1,b=2, a=b, a=2 #b = a+b b=2+2=4 n=n+1 return 'done'#異常時打印的消息運行結果:經過使用next的方式進行取值

print(f.__next__())

print(f.__next__())

print(f.__next__())

print(f.__next__())

print(f.__next__())

print(f.__next__())

print(f.__next__())

print(f.__next__())

print(f.__next__())

print(f.__next__())

print(f.__next__())

使用for循環那個return的down是沒法打印的

for i in f:

print(i)

使用next方法取數據取不出來了,就會拋出一個異常

Traceback (most recent call last):

File "D:\python\index.py", line 85, in <module>

print(f.__next__())

StopIteration: done

如何處理異常,可經過抓取異常

g=fib(6)

#異常處理代碼

while True:

try:

x = next(g)

print('g:', x)

except StopIteration as e:

print('Generator return value:', e.value)

最終運行結果:

g: 1

g: 1

g: 2

g: 3

g: 5

g: 8

Generator return value: done

===start loop===

 

爲何使用生成器

更容易使用,代碼量較小內存使用更加高效。好比列表是在創建的時候就分配全部的內存空間,而生成器僅僅是須要的時候才使用,更像一個記錄表明了一個無限的流。若是咱們要讀取並使用的內容遠遠超過內存,可是須要對全部的流中的內容進行處理,那麼生成器是一個很好的選擇,好比可讓生成器返回當前的處理狀態,因爲它能夠保存狀態,那麼下一次直接處理便可。流水線生成器。假設咱們有一個快餐記錄,這個記錄的地4行記錄了過去五年每小時售出的食品數量,而且咱們要把全部的數量加在一塊兒,求解過去5年的售出的總數。假設全部的數據都是字符串,而且不可用的數字被標記成N/A。那麼可使用下面的方式處理:結語

感謝閱讀,歡迎在評論區中發表本身不一樣的觀點,如有其餘問題請在評論區留言,喜歡的朋友請多多關注轉發支持一下。

原文出處:https://www.cnblogs.com/ceason/p/11629074.html

相關文章
相關標籤/搜索