Python小技巧5:需要動態生成列表的時候,考慮使用生成器替代
阿新 • • 發佈:2018-12-29
典型程式碼:
def mygen():
i = 0
while i < 100:
yield i
i += 1
if __name__ == '__main__':
gen = mygen()
for item in gen:
print(item)
什麼是生成器:
生成器是一個包含yield表示式的函式,只要一個函式中有了yield表示式,當呼叫這個函式的時候,函式體的程式碼壓根就不會執行,它只是會返回一個生成器物件。如果訪問一個生成器迭代器,每次訪問到的值都是動態生成的(比如典型程式碼中的變數i),即是yield右邊的值,並凍結當前狀態,等待下一次訪問。對於生成器物件可以將其理解為一種值的順序生成規則的描述,生成器物件會一直維護自己的生成規則上下文,直到結束(當然,也可以不結束)。
應用場景:
如果需求是動態的生成一個列表,然後其它函式會一次性訪問這個列表中的項,做相應的處理工作。
帶來的好處:
1. 不必返回整個列表物件,只返回生成規則描述,如果元素數量較大,可以節省大量記憶體。生成器甚至可以生成一個無限序列,只要生成規則永不停止即可。
2. 邏輯清晰,一眼就能看到值是如何返回的。
注意的點:
生成器物件是有狀態的,只能訪問一次。這也很容易理解,因為生成器只是一個值的生成規則,加上其上下文,不像列表一樣儲存了所有的值。
也可以使用原生的迭代器協議訪問生成器,但是需要手動處理迭代器結束時的StopIteration異常:
gen = mygen() while True: try: data = next(gen) print(data) except StopIteration: print('Iteration done') break