解析Python中的生成器及其與迭代器的差異
生成器
生成器是一種迭代器,是一種特殊的函數(shù),使用yield操作將函數(shù)構(gòu)造成迭代器。普通的函數(shù)有一個入口,有一個返回值;當函數(shù)被調(diào)用時,從入口開始執(zhí)行,結(jié)束時返回相應(yīng)的返回值。生成器定義的函數(shù),有多個入口和多個返回值;對生成器執(zhí)行next()操作,進行生成器的入口開始執(zhí)行代碼,yield操作向調(diào)用者返回一個值,并將函數(shù)掛起;掛起時,函數(shù)執(zhí)行的環(huán)境和參數(shù)被保存下來;對生成器執(zhí)行另一個next()操作時,參數(shù)從掛起狀態(tài)被重新調(diào)用,進入上次掛起的執(zhí)行環(huán)境繼續(xù)下面的操作,到下一個yield操作時重復上面的過程。Python的循環(huán)操作與C語言的實現(xiàn)不同,如果使用List等數(shù)據(jù)結(jié)構(gòu)需要耗費大量的內(nèi)容;循環(huán)操作中使用生成器只需要在內(nèi)存中實例化一個對象,可以減少內(nèi)存占用,提高循環(huán)操作的執(zhí)行速度。
>>>def myG(): ... yield 1 ... yield 2 ... yield 3 ... >>>g=myG() >>>next(g) 1 >>>next(g) 2 >>>next(g) 3 >>>next(g) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>>g2=myG() >>>for i in g2: ... print(i) 1 2 3
生成器表達式
for...[if]...語句可以簡潔的構(gòu)建一個List,同時也可以用來構(gòu)建生成器。
>>>a=[7,8,9] >>>b=[i**2 for i in a] >>>b [49, 64, 81] >>>ib=(i**2 for i in a) >>>ib <generator object <genexpr> at 0x7f72291217e0> >>>next(ib) 49 >>>next(ib) 64 >>>next(ib) 81 >>>next(ib) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
迭代器(Iterator)與生成器(Generator)的區(qū)別
迭代器是一個更抽象的概念,任何對象,如果它的類有next方法(next python3)和iter方法返回自己本身。
每個生成器都是一個迭代器,但是反過來不行。通常生成器是通過調(diào)用一個或多個yield表達式構(gòu)成的函數(shù)s生成的。同時滿足迭代器的定義。
當你需要一個類除了有生成器的特性之外還要有一些自定義的方法時,可以使用自定義的迭代器,一般來說生成器更方便,更簡單。
def squares(start, stop): for i in xrange(start, stop): yield i*i
等同于生成器表達式:
(i*i for i in xrange(start, stop))
列表推倒式是:
[i*i for i in xrange(start, stop)]
如果是構(gòu)建一個自定義的迭代器:
class Squares(object): def __init__(self, start, stop): self.start = start self.stop = stop def __iter__(self): return self def next(self): if self.start >= self.stop: raise StopIteration current = self.start * self.start self.start += 1 return current
此時,你還可以定義自己的方法如:
def current(self): return self.start
兩者的相同點:對象迭代完后就不能重寫迭代了。
相關(guān)文章
使用sklearn的cross_val_score進行交叉驗證實例
今天小編就為大家分享一篇使用sklearn的cross_val_score進行交叉驗證實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02python中的多線程鎖lock=threading.Lock()使用方式
這篇文章主要介紹了python中的多線程鎖lock=threading.Lock()使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06Pytorch上下采樣函數(shù)之F.interpolate數(shù)組采樣操作詳解
最近用到了上采樣下采樣操作,pytorch中使用interpolate可以很輕松的完成,下面這篇文章主要給大家介紹了關(guān)于Pytorch上下采樣函數(shù)之F.interpolate數(shù)組采樣操作的相關(guān)資料,需要的朋友可以參考下2022-04-04Python文件監(jiān)聽工具pyinotify與watchdog實例
今天小編就為大家分享一篇關(guān)于Python文件監(jiān)聽工具pyinotify與watchdog實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10Python操作Redis之設(shè)置key的過期時間實例代碼
這篇文章主要介紹了Python操作Redis之設(shè)置key的過期時間實例代碼,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下2018-01-01