Python筆記(十七):生成器

(一)生成器(Generator)算法

Python生成器是建立迭代器的簡單方法。簡單來講,生成器是一個函數,它返回一個咱們能夠迭代的對象(迭代器)(一次一個值)。app

由於下面會用到列表生成式,這裏先說明下列表生成式:函數

列表生成式:spa

theLi = [i*i for i in range(10)]

下面這段代碼的效果和上面的列表生成式是同樣的(一開始可能不太習慣列表生成式的寫法,多寫幾回就習慣了):3d

L = []
for i in range(10):
    L.append(i*i)

可在IDE中將結果打印出來. code

(二)建立生成器對象

一、將列表生成式的[]換成()就好了。blog

1 theLi = [i*i for i in range(10)]
2 
3 print(theLi)
4 #建立一個生成器
5 theGe = (i*i for i in range(10))
6 
7 print('生成器:',theGe)

 

能夠看到,print('生成器:',theGe)輸出的是一個生成器對象,不會直接輸出結果索引

二、在函數中定義yield語句就好了(執行到yield語句時,就會返回結果,不過生成器函數和普通函數仍是有區別的,下面會說明)內存

def theGe():
    i = 1
    yield i

print(type(theGe()))

(三)生成器函數和普通函數的區別

一、Generator函數包含一個或多個yield語句。

二、調用生成器函數時,它返回一個生成器對象,但不會當即執行。

三、生成器函數會自動實現__iter__()__next__()方法。

四、執行順序不一樣:普通函數執行到最後一句或者return語句時,就返回結果.而生成器函數,則是每次調用next()方法時執行,遇到yied語句就返回結果,再次執行時從上次結束的yield語句處開始執行.(執行順序的問題,設個斷點運行一次就清楚了)。

五、局部變量和狀態會被保存,一直到下一次調用。

六、函數結束時,拋出StopIteration異常。

舉個例子:

 1 from collections import Iterable
 2 from collections import Iterator
 3 
 4 def gen():
 5 
 6     i = 1
 7     print('第一次:',end='')
 8     yield i
 9     i += 1
10     print('第二次:',end='')
11     yield i
12     i += 1
13     print('第三次:',end='')
14     yield i
15 
16 print(type(gen()))
17 #生成器也是迭代器
18 print(isinstance(gen(),Iterable))
19 print(isinstance(gen(),Iterator))
20 
21 g = gen()
22 print(next(g))
23 print(next(g))
24 print(next(g))
25 print(next(g))

(四)生成器的使用

例如:使用生成器實現楊輝三角

 

比較簡單的一種理解方式,將每一行都當作一個列表,經過末尾補0的方式來計算下一行列表的值.

例如:咱們知道第二行的元素,咱們能夠經過下面這種方式得到三行的元素(這個規律是通用的)

 1 #第二行
 2 L2 = [1,1]
 3 
 4 L2.append(0) #此時變成了[1,1,0]
 5 
 6 
 7 L3  = []
 8 # 列表的索引爲-1的時候,值=0. L2[-1] = 0
 9 L3.append(L2[-1] + L2[0])
10 L3.append(L2[0]+L2[1])
11 L3.append(L2[1]+L2[2])
12 
13 print(L3)

而下面這段代碼

1 L3  = []
2 # 列表的索引爲-1的時候,值=0. L2[-1] = 0
3 L3.append(L2[-1] + L2[0])
4 L3.append(L2[0]+L2[1])
5 L3.append(L2[1]+L2[2])

其實就是:

L3  = []
for i in range(len(L2)):
    L3.append(L2[i-1] + L2[i])

也是(列表生成式的寫法):

1 L3  = [L2[i-1]+L2[i] for i in range(len(L2))]

實現楊輝三角:

 1 #楊輝三角
 2 def yhTriangles(n):
 3     yh = [1]
 4     while len(yh) <= n:
 5         yield yh
 6         yh.append(0)
 7         yh = [yh[i-1] + yh[i] for i in range(len(yh))]
 8 
 9 
10 for i in yhTriangles(10):
11     print(i)

(五)使用生成器的優點

一、易於實現,代碼更簡潔,容易閱讀。(例如:使用迭代器咱們須要本身去定義__iter__()和_next_()方法,而生成器會自動處理這些

二、對內存更加友好.例如:咱們建立一個列表的時候,是一建立就存放到內存中的,若是數據量很大,毫無疑問會佔用大量內存(而不少時候,咱們可能並不須要訪問全部數據)。若是列表元素能夠經過某種算法推算出來,一邊循環一邊計算,這樣就能節省大量的內存。Python的生成器就能夠實現這種功能.

三、生成器能夠表明一個無限的數據流.(無限的數據流是不能直接存放到內存中的,由於內存是有限的)

相關文章
相關標籤/搜索