Python 簡易手冊

單元 50 - 產生器

關鍵字 (keyword) yield 用作產生數值,只能用在函數 (function) 中,使之成為產生器 (generator) 函數,舉例如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 產生器函數
def do_something(n):
    for i in range(n):
        if i % 2 != 0:
            # 產生數字
            yield i

# 呼叫產生器函數
a = do_something(10)
# 依序取得產生器函數產生的數字
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))

# 檔名: yield_demo.py
# 說明: 《Python簡易手冊》的範例
# 網址: http://kaiching.org
# 作者: Kaiching Chang
# 時間: 2024 年 3 月

第 6 行,關鍵字 yield 在函數 do_something() 中產生 for 迴圈取得的奇數

 1
 2
 3
 4
 5
 6
# 產生器函數
def do_something(n):
    for i in range(n):
        if i % 2 != 0:
            # 產生數字
            yield i

單元 44 - 函數與 return 陳述介紹如何定義函數,單元 23 - for 陳述介紹如何使用 for 迴圈 (loop) ,單元 38 - 序對與 Range介紹 range 資料型態,這裡判斷奇數是用 if 陳述 (statement) ,單元 20 - if 陳述介紹 if 的用法。

第 9 行呼叫產生器函數

 8
 9
# 呼叫產生器函數
a = do_something(10)

下面用五次內建函數 (built-in function) next() 印出產生器 a 的值

10
11
12
13
14
15
# 依序取得產生器函數產生的數字
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))

產生器其實就是迭代器 (iterator) 的語法糖,所以跟迭代器一樣是用 next() 取值,此例執行結果如下

> python yield_demo.py
1
3
5
7
9
>

單元 66 - 迭代器會介紹如何定義迭代器。

原本函數中只能用 returnyield 二選一,基本上就是讓函數只能回傳或是只能產生,後來 Python 允許在產生器函數中用 return 陳述,這樣產生器函數除了產生外有回傳的功能,倒是取得回傳值要用另一個委派函數,以 yield from 取得回傳值 (return value) ,舉例如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 產生器函數
def do_something(n):
    # 暫存總和
    sum = 0
    # 進行產生及加總
    for i in range(n):
        if i % 2 != 0:
            # 進行加總
            sum += i
            # 產生數字
            yield i
    # 回傳總和
    return sum

# 產生器的委派函數
def do_something2(n):
    y = yield from do_something(n)
    print(y)

# 呼叫函數
a = do_something2(10)
# 印出產生的值
for i in a:
    print(i)

# 檔名: yield_demo2.py
# 說明: 《Python簡易手冊》的範例
# 網址: http://kaiching.org
# 作者: Kaiching Chang
# 時間: 2024 年 3 月

上例的 do_something() 加入 sum 計算產生所有數字的總和,最後也回傳 sum ,如果要使用 do_something() 的回傳值,就在委派函數 do_something2() 中以 yield from 取得

15
16
17
18
# 產生器的委派函數
def do_something2(n):
    y = yield from do_something(n)
    print(y)

這裡是印出 do_something() 的回傳值,然後執行部分是用 do_something2() 建立產生器變數,以 for 迴圈印出產生器變數的值

20
21
22
23
24
# 呼叫函數
a = do_something2(10)
# 印出產生的值
for i in a:
    print(i)

注意,如果是用 do_something() 建立產生器變數,那就不會取得回傳值,此例執行結果如下

> python yield_demo2.py
1
3
5
7
9
25
>

參考資料

上一頁 單元 49 - pass 陳述與省略符號 ...
回 Python 簡易手冊 首頁
下一頁 單元 51 - 產生器運算式
回 Python 教材首頁
回程式語言教材首頁