生成器的理解

2022-05-06 04:48:12 字數 2577 閱讀 6805

在python中,一邊迴圈一邊計算的機制,稱為生成器:generator。

列表所有資料都在記憶體中,如果有海量資料的話將會非常耗記憶體。

如:僅僅需要訪問前面幾個元素,那後面絕大多數元素占用的空間都白白浪費了。

如果列表元素按照某種演算法推算出來,那我們就可以在迴圈的過程中不斷推算出後續的元素,這樣就不必建立完整的list,從而節省大量的空間。

簡單一句話:我又想要得到龐大的資料,又想讓它占用空間少,那就用生成器!

第一種方法很簡單,只要把乙個列表生成式的改成(),就建立了乙個generator:

>>> l = [x * x for x in range(10)]

>>> l

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

>>> g = (x * x for x in range(10))

>>> g

at 0x1022ef630>

建立lg的區別僅在於最外層的()l是乙個list,而g是乙個generator。

方法二, 如果乙個函式中包含yield關鍵字,那麼這個函式就不再是乙個普通函式,而是乙個generator。呼叫函式就是建立了乙個生成器(generator)物件。

(1)生成器(generator)能夠迭代的關鍵是它有乙個next()方法,

工作原理就是通過重複呼叫next()方法,直到捕獲乙個異常。

(2)帶有 yield 的函式不再是乙個普通函式,而是乙個生成器generator。

可用next()呼叫生成器物件來取值。next 兩種方式 t.__next__()  |  next(t)。

可用for 迴圈獲取返回值(每執行一次,取生成器裡面乙個值)

(基本上不會用next()來獲取下乙個返回值,而是直接使用for迴圈來迭代)。

(3)yield相當於 return 返回乙個值,並且記住這個返回的位置,下次迭代時,**從yield的下一條語句開始執行。

(4).send() 和next()一樣,都能讓生成器繼續往下走一步(下次遇到yield停),但send()能傳乙個值,這個值作為yield表示式整體的結果

——換句話說,就是send可以強行修改上乙個yield表示式值。比如函式中有乙個yield賦值,a = yield 5,第一次迭代到這裡會返回5,a還沒有賦值。第二次迭代時,使用.send(10),那麼,就是強行修改yield 5表示式的值為10,本來是5的,那麼a=10

感受下yield返回值的過程(關注點:每次停在哪,下次又開始在哪)及send()傳參的通訊過程,

思考none是如何產生的(第一次取值:yield 返回了 i 值 0,停在yield i,temp沒賦到值。第二次取值,開始在print,temp沒被賦值,故列印none,i加1,繼續while判斷,yield  返回了 i 值 1,停在yield i):

好了,話不多說,翠花,上栗子:

1 #encoding:utf-8  

2 def yield_test(n):

3 for i in range(n):

4 yield call(i)

5 print("i=",i)

6 print("done.")

7

8 def call(i):

9 return i*2

10

11 for i in yield_test(5):

12 print(i,",")

結果:

>>>   

0 ,

i= 0

2 ,

i= 1

4 ,

i= 2

6 ,

i= 3

8 ,

i= 4

done.

>>>

什麼是生成器?

生成器僅僅儲存了一套生成數值的演算法,並且沒有讓這個演算法現在就開始執行,而是我什麼時候調它,它什麼時候開始計算乙個新的值,並給你返回。

def count_down(n):

while n >= 0:

newn = yield n

print('newn', newn)

if newn:

print('if')

n = newn

print('n =', n)

else:

n -= 1

cd = count_down(5)

for i in cd:

print(i, ',')

if i == 5:

cd.send(3)

結果:

理解 Python 生成器

什麼時候呼叫,什麼時候計算並返回值 生成器僅僅儲存了一套生成數值的演算法,並且沒有讓這個演算法現在就開始執行,而是我什麼時候調它,它什麼時候開始計算乙個新的值,並給你返回。在python中,一邊迴圈一邊計算的機制,稱為生成器 generator。列表耗記憶體 列表所有資料都在記憶體中,如果有海量資料...

對生成器的理解

迭代器 對於可迭代物件使用內建函式iter 獲取迭代器物件。迭代器物件通過next 方法來訪問裡面的元素 當容器中沒有可訪問的元素後,next 方法將會丟擲乙個stopiteration異常終止迭代器。列表生成式 例 x 2 for x in range n 生成器表示式 通列表解析語法,把列表解析...

對於生成器的理解

什麼是生成器呢?生成器就是一次生成乙個值的函式 就像是一把自動步槍,生成器中的值就它的子彈,槍平時都會有保險,在關保險的時候怎麼扣扳機都不會射出子彈 而自動步槍呢還可以單點和全自動兩個模式進行射擊.舉個例子 def func for i in range 100 yield i 這就是個簡單的生成器...