產生器/生成器 Generators


Generator 是一種特殊的迭代器,使用 yield 關鍵字生成值,而不是一次性返回所有值。Generator能夠在執行過程中暫停,保留當前狀態,並在下一次被調用時繼續執行。生成器以lazy loading (惰性加載) 的方式處理數據,適合處理需要大量記憶體的數據流或無限序列。

lazy loading (惰性加載) :  惰性加載是一種優化策略,指的是僅在需要時才加載或初始化資源,而非在程序啟動時就一次性加載所有內容。這種方法可以減少記憶體使用和提升應用啟動速度,特別適合處理大量數據或昂貴的操作。

以下會介紹幾種Generator的使用方式

  • 生成 1 到 n 的平方數,定義square_numbers函數做為一個Generator Function,yield則是generator的關鍵,他與return差異在於
    • return: 整支function執行完回傳對應結果
    • yield: function執行到這行會執行完回傳當下的值,以下例來說,會回傳 i ** 2,e.g. i的平方

所以在下面例子,我是在產生器函數Generator Function傳入5也就是會產生1~5的平方回傳並賦值給square。

執行順序為

  1. 傳入5作為Generator Function參數
  2. for迴圈內會執行 i = 1,計算1的平方,執行yield 1回傳1並且暫停函數
  3. 產生器函數回傳值的1放入square
  4. 這時因為python會自動在for迴圈引入next()函數,此函數會自動被執行至完整執行完生成器函數的結果。
  5. next()函數會直接讓i=2繼續執行,因此yield返回值是4,存入square,並印出來
  6. 依序執行i = 3, 4, ,5直到停止條件
def square_numbers(n):
  for i in range(1, n + 1):
    yield i**2
 
for square in square_numbers(5):
  print(square)
  • 生成費波那契數列 (Fibonacci Sequence): 產生器的特性能很好的產生費式數列,由於yield函數,我們可以耗費較少記憶體還計算費式數列

for裡面的"_"在python裡代表的是不需要使用的變數,然後一樣fibonacci產生器函數,a, b = 0, 1為python 可以使用的語法,代表0賦值給a,1賦值給b,下面a,b = b, a + b也是同理。

在fibonacci產生器函數中的執行順序,6作為產生器函數的傳入參數,代表在產生器裡要執行6次,那對應結果是

a = 0, b = 1 -> 執行yield a並且返回函數,賦值給num,印出num

for迴圈自動執行next()函數,從yield函數開始往下執行。

a = b, b = a + b -> a = 1, b = 0 + 1,yield a = 1,賦值給num並印出

照此流程依序會執行

a = 1, b = 1 + 1 = 2

a = 2, b = 1 + 2 = 3

a = 3, b = 2 + 3 = 5

a = 5, b = 3 + 5 = 8

a = 8, b = 5 + 8 = 13

def fibonacci(n):
  a, b = 0, 1
  for _ in range(n):
    yield a
    a, b = b, a + b
for num in fibonacci(6):
  print(num)

這麼一來我們可以不用宣告一堆記憶體空間來儲存數列,便可以動態配置空間來傳遞參數。

  • 產生5個質數: 接下來的應用也類似就不每個步驟解析了,利用質數的判斷式來寫
def is_prime(num):
  if num < 2:
    return False
  for i in range(2, int(num**0.5) + 1):
    if num % i == 0:
    return False
  return True
 
 
def prime_numbers(n):
  count = 0
  num = 2
  while count < n:
    if is_prime(num):
    yield num
    count += 1
  num += 1
for prime in prime_numbers(5):
  print(prime)

 

目前還沒感受到Generator的強大之處,不過會被設計出來一定有他的理由,可能目前還沒碰到大型專案,對於記憶體配置比較沒有要求。希望以後能有機會看看在大型專案上這些東西是怎麼被應用的。

文章標籤
全站熱搜
創作者介紹
創作者 Luke 的頭像
Luke

Luke的部落格

Luke 發表在 痞客邦 留言(0) 人氣(7)