Last Updated on 2023-07-11 by Clay
介紹
yield
是 Python 中的一個關鍵字,它的使用場景與 return
很像,不過使用 yield
會把函式變成一個生成器(generator)。
什麼是生成器呢?生成器可以想像成一個更加簡單直接的迭代器(iterator),它的主要優點是可以延遲計算與延遲生成返回值,也就是說每次調用生成器函式迭代時才會進行運算。這對於大量級的計算或無窮數列來說非常有用 —— 至少你不用一次性地將所有資料載入記憶體。
以下來看個簡單的例子。
yield 與 next() 範例程式碼
除了直接用 for
迴圈取值外,我們也可以使用 iter()
搭配 next()
來取值。
直得一提的是,每次呼叫 infinite_sequence()
時都會創建一個新的生成器,所以才會看到兩次從 1 開始的數字。
# coding: utf-8
from typing import Iterator
def infinite_sequence() -> Iterator[int]:
num = 0
while True:
num += 1
yield num
def main() -> None:
# For Loop
for i in infinite_sequence():
print("for", i)
if i >= 5:
break
# Next
sequence_iterator = iter(infinite_sequence())
print("next", next(sequence_iterator))
print("next", next(sequence_iterator))
print("next", next(sequence_iterator))
print("next", next(sequence_iterator))
print("next", next(sequence_iterator))
if __name__ == "__main__":
main()
Output:
for 1 for 2 for 3 for 4 for 5 next 1 next 2 next 3 next 4 next 5
如果要看到同樣的數字,則要在一開始就將其包成迭代器。
# coding: utf-8
from typing import Iterator
def infinite_sequence() -> Iterator[int]:
num = 0
while True:
num += 1
yield num
def main() -> None:
# Init
sequence_iterator = iter(infinite_sequence())
# For Loop
for i in sequence_iterator:
print("for", i)
if i >= 5:
break
# Next
print("next", next(sequence_iterator))
print("next", next(sequence_iterator))
print("next", next(sequence_iterator))
print("next", next(sequence_iterator))
print("next", next(sequence_iterator))
if __name__ == "__main__":
main()
Output:
for 1 for 2 for 3 for 4 for 5 next 6 next 7 next 8 next 9 next 10
在第二個版本中,我們會看到使用 for
迴圈與 next()
都是對同一個迭代器了。