Python 生成器(Generators)教學指南 | Python
2026/04/24
在 Python 中,生成器(Generators) 是一種特殊的迭代器,能以惰性求值的方式逐一產出資料,而非一次將所有資料載入記憶體。本篇將帶你認識 yield 關鍵字、生成器表達式,以及如何利用生成器高效處理大型資料集。
什麼是生成器?
生成器(Generator)是一種特殊的函式,使用 yield 關鍵字來產出值。每次呼叫 next() 時,函式會從上次暫停的位置繼續執行,直到遇到下一個 yield 或函式結束:
def count_up(n):
i = 1
while i <= n:
yield i
i += 1
gen = count_up(3)
print(next(gen)) # 輸出:1
print(next(gen)) # 輸出:2
print(next(gen)) # 輸出:3
一般函式使用 return 回傳結果後就結束執行,而生成器函式使用 yield 暫停並保留狀態,下次呼叫時從暫停處繼續。
生成器表達式
生成器表達式的語法類似串列推導式(List Comprehension),但使用小括號 () 而非方括號 [],不會一次建立完整串列:
# 串列推導式:一次建立整個串列
squares_list = [x ** 2 for x in range(10)]
# 生成器表達式:惰性產出,節省記憶體
squares_gen = (x ** 2 for x in range(10))
# 可直接傳入函式
total = sum(x ** 2 for x in range(10))
print(total) # 輸出:285
yield from 與 send()
yield from 可以將迭代委派給子生成器;send() 則能在執行過程中向生成器傳入值:
def chain(*iterables):
for it in iterables:
yield from it
print(list(chain([1, 2], [3, 4]))) # 輸出:[1, 2, 3, 4]
def accumulator():
total = 0
while True:
value = yield total
if value is None:
break
total += value
acc = accumulator()
next(acc) # 啟動生成器,輸出:0
print(acc.send(10)) # 輸出:10
print(acc.send(20)) # 輸出:30
記憶體效率比較
生成器最大的優勢在於記憶體效率。串列會將所有元素存在記憶體中,而生成器每次只產出一個值:
import sys
big_list = [i for i in range(1000000)]
print(sys.getsizeof(big_list)) # 輸出:約 8448728 bytes
big_gen = (i for i in range(1000000))
print(sys.getsizeof(big_gen)) # 輸出:約 200 bytes
實用範例
處理大型檔案時,生成器能避免一次載入整個檔案;也非常適合表示無限序列:
# 逐行讀取大型檔案
def read_large_file(file_path):
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
yield line.strip()
# 無限費氏數列
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
for _ in range(8):
print(next(fib), end=" ")
# 輸出:0 1 1 2 3 5 8 13
總結
生成器是 Python 中處理大量資料的利器。透過 yield 關鍵字,生成器以惰性求值的方式逐一產出資料,大幅降低記憶體使用量。無論是讀取大型檔案、建立無限序列,還是串接多個資料來源,生成器都能讓程式碼更高效。希望這篇文章能幫助你理解並善用 Python 生成器。
生成器是迭代器的進階應用,建議先閱讀 Python 迭代器教學。生成器表達式的語法與串列推導式相似,可參考 Python 串列推導式教學。