Python 生成器:記憶體高效的迭代器
了解如何使用Python生成器和yield语句以最小的内存占用处理巨大的数据集。掌握生成器表達式。
概述
當編寫處理數千或數百萬筆記錄的程式碼時,記憶體管理變得至關重要。如果將整個資料集載入到清單中,則可能會耗盡 RAM 並使伺服器崩潰。 Python 生成器通过提供按需流数据的机制解决了这个问题。生成器不是一次計算整個資料集並將其儲存在記憶體中,而是一次產生一個項目,將其交給呼叫者,並暫停其執行,直到請求下一個項目。
生成器的定義與普通函數類似,但它們使用“yield”關鍵字而不是“return”。當呼叫生成器函數時,它會傳回一個生成器迭代器對象,而不執行函數的內部語句。當呼叫者在生成器上呼叫“next()”(或對其進行循環)時,該函數將執行直到達到“yield”。此時,生成器產生值,保存其局部變量,並暫停執行。當再次呼叫時,它會從上次中斷的地方繼續執行。
您也可以使用生成器表達式建立生成器,該表達式使用與清單推導式相同的語法,但用括號“(...)”而不是方括號“[...]”括起來。這使得用記憶體高效的迭代器替換列表推導式變得異常容易。透過避免大量記憶體分配,生成器對於處理大型日誌、從資料庫串流傳輸資料或對無限長度的數學序列執行計算是必不可少的。
程式碼和執行輸出
產生斐波那契數的自訂生成器和記憶體高效的生成器表達式。
generators_demo.py
在編輯器中嘗試def fibonacci_generator(limit):
"""Yields Fibonacci numbers up to the limit."""
a, b = 0, 1
count = 0
while count < limit:
yield a
a, b = b, a + b
count += 1
# Instantiate generator
fib = fibonacci_generator(5)
print("--- Using Generator Function ---")
for num in fib:
print(num)
# Generator expression (squares of numbers)
squares_gen = (x**2 for x in range(1, 1000000))
print("\n--- Using Generator Expression ---")
print(next(squares_gen))
print(next(squares_gen))
print(next(squares_gen))端子輸出
--- Using Generator Function ---
0
1
1
2
3
--- Using Generator Expression ---
1
4
9逐步實施
- 逐行讀取對於 RAM 來說太大的文件
- 產生 ID 或數學數字的無限序列
- 批量串流資料庫記錄以處理 API 呼叫
常見問題解答
收益率和回報有什麼不同?
return 完全終止函數。 Yield 產生一個值並暫停函數,保存其狀態,以便在請求時可以恢復。
當生成器用完物品時會發生什麼事?
它引發 StopIteration 異常。在「for」循環下,Python 會自動攔截此異常以乾淨地終止循環。
相關主題
推薦的 Python 資源
透過相關的互動式教學、備忘單和程式碼比較來擴展您的知識。