原标題:Python生成器之懶人版本的疊代器
從容器、可疊代對象談起
所有的容器都是可疊代的(iterable),疊代器提供了一個next方法。iter()傳回一個疊代器,通過next()函數可以實作周遊。
除了數字外,其他資料結構都是可疊代的。
生成器是什麼
生成器是懶人版本的疊代器。例:
[i for i in range(100000000)] 聲明了一個疊代器,每個元素在生成後都會儲存到記憶體中,占用了巨量的記憶體。(i for i in range(100000000)) 初始化了一個生成器,可以看到,生成器并不會像疊代器一樣占用大量的記憶體,相比于 test_iterator(),test_generator()函數節省了一次生成一億個元素的過程。在調用next()的時候,才會生成下一個變量.
生成器能玩啥花樣
數學中有一個恒等式,(1 + 2 + 3 + … + n)^2 = 1^3 + 2^3 + 3^3 + … + n^3,用以下代碼表達
generator()這個函數,它傳回了一個生成器,當運作到yield i ** k時,暫停并把i ** k作為next()的傳回值。每次調用next(gen)時,暫停的程式會啟動并往下執行,而且i的值也會被記住,繼續累加,最後next_1為8,next_3為512.
仔細檢視這個示例,發現疊代器是一個有限集合,生成器則可以成為一個無限集。調用next(),生成器根據運算會自動生成新的元素,然後傳回給你,非常便捷。
再來看一個問題:給定一個list和一個指定數字,求這個數字在list中的位置:
再看一例子:
查找子序列:給定兩個字元串a,b,查找字元串a是否字元串b的子序列,所謂子序列,即一個序列包含在另一個序列中并且順序一緻。[1,3,5]是[1,2,3,4,5]子序列,而[1,4,3]不是 [1,2,3,4,5] 的子序列.
算法:分别用兩個指針指向兩個字元串的頭,然後往後移動找出相同的值,如果其中一個指針走完了整個字元串也沒有相同的值,則不是子序列
下面代碼為上面代碼的演化版本
首先iter(b)把b轉為疊代器。目的是内部實作next函數,(i for i in a) 會産生一個生成器 ,同樣((i in b) for i in a)也是。然後(i in b)等階于:
這裡非常巧妙地利用生成器的特性,next()函數運作的時候,儲存了目前的指針。比如下面這個示例
責任編輯: