Python學習札記 十八 高階特性4 生成器

2021-09-07 09:04:29 字數 4077 閱讀 3424

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字典...