Python generator

Python Generator 介紹

Python generator object 其實是 iterator 的一種,所以一樣有 iterator 的特性:

  • 只能 iterate 一次
  • 可以用 next function 取得 iteration 的下一個 item
延伸閱讀:Python Iterator 介紹

1. 宣告 Python Generator

1.1 Generator Expression

Generator Expression 和 Comprehension 語法類似,只是將 expression 用 () 給包起來。

延伸閱讀:Python Comprehension 語法 – List Comprehension, Set Comprehension, Dict Comprehension
# List Comprehension 表示法
my_comprehension = [i for i in range(5)]
my_generator = (i for i in range(5))

print(my_comprehension)
[0, 1, 2, 3, 4]
print(my_generator)
<generator object <genexpr> at 0x104231970>

可以看到,用 generator expression 可以用來宣告 generator object。

如上述提到的,generator 其實算是 iterator 的一種,所以我們可以根據 iterator 的定義:有 __iter__() 和 __next__() methods 的 object,來確認他是不是 iterator。

from collections.abc import Iterator

my_generator = (i for i in range(5))

print(hasattr(my_generator, '__iter__'))
True
print(hasattr(my_generator, '__next__'))
True

print(isinstance(my_generator, Iterator))
True

因此,generator 也依樣具備了 iterator 的特性:

my_generator = (i for i in range(5))

print(next(my_generator))
0
print(next(my_generator))
1
print(next(my_generator))
2
print(next(my_generator))
3
print(next(my_generator))
4
print(next(my_generator))
StopIteration

1.2 generator function

第二種宣告 generator 的方式,是使用 generator function,只要在 function 的定義中有出現 yield,那這個 function 就會變成 generator function

def yield_generator():
    yield('Hello')

my_generator = yield_generator()
print(my_generator)
<generator object yield_generator at 0x1002749e0>

當執行 generator function 的時候,並不會真的執行 function,而是會 new 出一個 generator object,可以用 for loop 或是 next function 來 iterate 這個 generator object。

每當執行 next function 時,才會真的執行 generator function,碰到 yield 的時候會再把控制權丟出來,直到再次執行 next function,才會從上次 yield 的地方繼續往下執行,直到碰到下一個 yield:

def yield_generator():
    print('start')
    yield('Hello')
    print('keep executing')
    yield('world')

my_generator = yield_generator()
print(next(my_generator))
start
Hello
print(next(my_generator))
keep executing
world
print(next(my_generator))
StopIteration

可以用 while loop 和 yield 搭配使用:

def yield_generator(max):
    n = 0
    a = 2
    while n < max:
        yield(a)
        a = a ** 2
        n = n + 1
    
my_generator = yield_generator(3)
print(next(my_generator))
2
print(next(my_generator))
4
print(next(my_generator))
16
print(next(my_generator))
StopIteration

參考資料

產生器 generator – Python 教學 – STEAM 教育學習網
How to Use Generators and yield in Python

如果覺得我的文章有幫助的話,歡迎幫我的粉專按讚哦~謝謝你!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top