1. 程式人生 > 實用技巧 >第49講:亂入——生成器

第49講:亂入——生成器

一 生成器相關概念

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

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

2 為什麼要有生成器?

  • 列表所有資料都在記憶體中,如果有海量資料的話將會非常耗記憶體。
  • 如:僅僅需要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。
  • 如果列表元素按照某種演算法推算出來,那我們就可以在迴圈的過程中不斷推算出後續的元素,這樣就不必建立完整的list,從而節省大量的空間。
  • 簡單一句話:我又想要得到龐大的資料,又想讓它佔用空間少,那就用生成器!

3 如何建立生成器?

  • 第一種方法:把一個列表生成式的[]改成(),就建立了一個generator。
  • 1 >>> e = (i for i in range(10))
    2 >>> e
    3 <generator object <genexpr> at 0x000000FA17E39E40>
  • 第二種方法: 如果一個函式中包含yield關鍵字,那麼這個函式就不再是一個普通函式,而是一個generator。呼叫函式就是建立了一個生成器(generator)物件。
  •  1 >>> def myGen():
     2 ...     print
    ("生成器被執行!") 3 ... yield 1 4 ... yield 2 5 ... 6 >>> myG = myGen() 7 >>> next(myG) 8 生成器被執行! 9 1 10 >>> next(myG) 11 2 12 >>> next(myG) 13 Traceback (most recent call last): 14 File "<stdin>", line 1, in <module> 15 StopIteration

4 生成器的工作原理

(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

參考網站:https://www.cnblogs.com/liangmingshen/p/9706181.html