目錄
一、生成器介紹
1.1 生成器與迭代器的關系
1.2 生成器與return比較
二、創建生成器
方法1: 生成器函數
方法2: 生成器表達式
三、生成器的實際應用場景
3.1 處理大型文件
3.2 生成無限序列
3.3 數據管道處理
四、生成器的高級用法
4.1 使用send()方法傳遞值
4.2 生成器委托(yield from)
五、生成器的特點
總結
一、生成器介紹
????????生成器是Python中一種特殊的迭代器,關鍵字是yield,
它允許你按需生成值,而不是一次性計算并存儲所有值。這種"惰性計算"的特性使得生成器在處理大數據集或無限序列時非常高效。
1.1 生成器與迭代器的關系
????????生成器是一種特殊的迭代器,具有迭代器的所有特性,但更簡潔。生成器自動實現了迭代器協議(即__iter__()和__next__()方法),并且狀態掛起和恢復是自動的。
????????迭代器是一個可以記住遍歷位置的對象,它從集合的第一個元素開始訪問,直到所有元素被訪問完結束,只能往前不會后退。生成器是使用yield表達式來生成值的函數,每次調用next()時,生成器會從上次yield的位置繼續執行,直到遇到yield或return(包括函數結束)為止。
????????生成器是迭代器的一種,但迭代器不一定是生成器。
- 迭代器可以通過實現類的__iter__和__next__方法來創建
- 生成器通過函數和yield來創建。
1.2 生成器與return比較
- 普通函數使用
return
返回結果后,其執行狀態就會被銷毀。 - 生成器使用
yield
關鍵字,在返回值的同時會保存當前執行狀態,下次調用時可以從上次暫停的地方繼續執行。
? ? ? 通俗的說,yield就是和return一樣執行到該位置時返回變量值,但函數不會結束退出,而是暫停在這個位置掛起任務,等待下一次next()調用時,從暫停的位置繼續執行。
二、創建生成器
方法1: 生成器函數
使用yield
關鍵字代替return
的函數就是生成器函數:
def simple_generator():yield 1yield 2yield 3# 使用生成器
gen = simple_generator()
print(next(gen)) # 輸出: 1
print(next(gen)) # 輸出: 2
print(next(gen)) # 輸出: 3
方法2: 生成器表達式
類似列表推導式,但使用圓括號:
# 列表推導式 - 立即計算所有值
squares_list = [x*x for x in range(5)] # [0, 1, 4, 9, 16]# 生成器表達式 - 按需生成值
squares_gen = (x*x for x in range(5))
print(next(squares_gen)) # 輸出: 0
print(next(squares_gen)) # 輸出: 1
三、生成器的實際應用場景
3.1 處理大型文件
def read_large_file(file_path):"""逐行讀取大文件,避免內存溢出"""with open(file_path, 'r') as file:for line in file:yield line.strip()# 使用生成器處理GB級文件
for line in read_large_file('huge_file.txt'):process_line(line) # 每次只處理一行,不占用大量內存
3.2 生成無限序列
def fibonacci():"""生成無限斐波那契數列"""a, b = 0, 1while True:yield aa, b = b, a + b# 獲取前10個斐波那契數
fib_gen = fibonacci()
first_10 = [next(fib_gen) for _ in range(10)]
print(first_10) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
3.3 數據管道處理
def numbers():for i in range(10):yield idef square(nums):for num in nums:yield num ** 2def even_filter(nums):for num in nums:if num % 2 == 0:yield num# 構建數據處理管道
result = even_filter(square(numbers()))
print(list(result)) # [0, 4, 16, 36, 64]
四、生成器的高級用法
4.1 使用send()方法傳遞值
def generator_with_send():value = yield "開始"while True:value = yield f"收到: {value}"gen = generator_with_send()
print(next(gen)) # 輸出: "開始"
print(gen.send("你好")) # 輸出: "收到: 你好"
print(gen.send("世界")) # 輸出: "收到: 世界"
4.2 生成器委托(yield from)
def sub_generator():yield from range(3)yield from ['a', 'b', 'c']for item in sub_generator():print(item) # 輸出: 0, 1, 2, 'a', 'b', 'c'
五、生成器的特點
優勢:
-
內存效率:一次只產生一個值,不占用大量內存
-
惰性計算:需要時才計算,避免不必要的運算
-
代碼簡潔:用簡潔的語法表達復雜的迭代邏輯
-
流水線處理:可以構建高效的數據處理管道
缺點:
-
生成器只能迭代一次,迭代完后需要重新創建
-
不適合需要隨機訪問的場景
-
調試可能比普通函數復雜
總結
????????生成器是Python中強大而高效的工具,特別適合處理大數據流、構建數據處理管道和創建無限序列。通過掌握生成器,你可以編寫出更加內存友好和Pythonic的代碼。