1.通過列表生成式,我們可以直接建立乙個列表。但是,受到記憶體限制,列表容量肯定是有限的,且容易造成空間浪費。所以,如果列表元素可以按照某種演算法推算出來,那我們可以在迴圈的過程中不斷推算出後續的元素,這樣就不必建立完整的list,從而節省大量的空間,在python中這種機制稱為生成器:generator。
注意:generator儲存的是演算法。第一種生成generator的方法很簡單,將列表生成式的括號改為()即可:
#!/usr/bin/env python3
l = [i*i for i in range(1, 11)]
g = (i*i for i in range(1, 11))
print(l)
print(g)
sh-3.2# ./generator1.py
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
at 0x101be17d8>
如果想要乙個乙個列印出來generator的元素,可以借助next()函式來訪問。
>>> g = (i*i for i in range(1, 11))
>>> next(g)
1>>> next(g)
4>>> next(g)
9>>> next(g)
16>>> next(g)
25>>> next(g)
36>>> next(g)
49>>> next(g)
64>>> next(g)
81>>> next(g)
100>>> next(g)
traceback (most recent call last):
file "", line 1, in stopiteration
generator儲存的是演算法,在呼叫next()函式的時候是先用儲存的演算法計算得到值再輸出。next()函式在越界的時候報「stopiteration」錯誤。
但是= =,generator基本不用next()函式。一般使用for迴圈輸出元素。
for i in g :
print(i)
149
1625
3649
6481
100
2.generator非常強大。如果推算的演算法比較複雜,用類似列表生成式的for迴圈無法實現的時候,還可以用函式來實現。
比如斐波那契數列:
def fib(maxn) :
i, a, b = 1, 1, 1
print(1)
while i < maxn:
print(b)
a, b = b, a+b
i = i+1
輸出斐波那契數列的前n個數。
>>> from generator1 import fib
>>> fib(5)11
235>>> fib(10)11
2358
1321
3455
注意語句:i, a, b = 1, 1, 1
仔細觀察,可以看出,fib函式實際上是定義了斐波拉契數列的推算規則,可以從第乙個元素開始,推算出後續任意的元素,這種邏輯其實非常類似generator。也就是說,這種演算法也可以通過generator的方法進行儲存。
改動為generator也很簡單:print(b) => yield(b)。
def fib1(maxn) :
i, a, b = 0, 0, 1
while i < maxn:
yield(b)
a, b = b, a+b
i = i+1
>>> from generator1 import fib1
>>> fib1(5)
>>> fib1(10)
這裡,最難理解的就是generator和函式的執行流程不一樣。函式是順序執行,遇到return語句或者最後一行函式語句就返回。而變成generator的函式,在每次呼叫next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。注意理解這段話:
def exp():
print('step 1:')
yield(1)
print('step 2:')
yield(3)
print('step 3:')
yield(5)
exp()函式內含yield()語句,因而是乙個generator。
>>> from generator1 import exp
>>> exp()
呼叫exp()函式時,需要先建立乙個generator物件,並通過next()函式執行generator。
>>> output = exp()
>>> print(next(output))
step 1:
1>>> print(next(output))
step 2:
3>>> print(next(output))
step 3:
5>>> print(next(output))
traceback (most recent call last):
file "", line 1, in stopiteration
因此,generator在呼叫next()函式時執行,在遇見yield()語句時返回。
當然,我們在函式也盡量避免使用next()函式,使用迭代取代next。
>>> for i in fib1(5):
... print(i)
... 11
235
楊輝三角定義如下:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
my answer:
def ********s():
i = 1
l =
while i <= 10:
l1 =
if i > 1 :
for j in range(1, i-1):
# print('i', i, 'j', j)
a, b = int(l[j]), int(l[j-1])
# print(a, b)
if i > 1 :
yield(l1)
i = i+1
l = l1
n = 0
for t in ********s():
print(t)
n = n + 1
if n == 10:
break
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
sh-3.2#
2017/2/7
Python學習札記 二十八 模組1
1.模組 乙個.py檔案稱為乙個模組。2.模組化的意義 a.提公升程式的可維護性 b.不用重複造輪子 3.避免模組衝突,解決方法 引入了按目錄來組織模組的方法,稱為包 package eg.abc.py abc模組,xyz.py xyz模組 倘若出現衝突 選擇乙個頂層資料夾名稱,盡量保證名稱唯一 m...
python學習筆記(三) python高階特性
python的高階特性有切片 迭代 列表生成式 生成器 迭代器等,下面來介紹這幾種高階特性 1 切片 切片特別簡單,用中括號表示範圍,包前不包後。就是中括號裡邊的範圍前面的數值被包括在內,後面的數值不被包括在內。l a b c d l 0 3 索引從0開始取到3,不包括3.索引從0開始,0可以省略 ...
Python學習札記
1 strip 去除字串中所有不想要的空白符,split 方法建立乙個列表。2 sorted bif支援複製排序。3 分片,列表推導 4 工廠函式去除掉裡列表中重複的項。5 定義乙個類時,實際上是在定義乙個定製工廠函式。6 使用dict 工廠函式或使用 可以建立乙個空字典。要訪問乙個person字典...