這篇文章將為大家詳細(xì)講解有關(guān)Python中生成器與迭代器有什么區(qū)別,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
成都創(chuàng)新互聯(lián)公司長(zhǎng)期為近千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為潮南企業(yè)提供專業(yè)的成都做網(wǎng)站、網(wǎng)站設(shè)計(jì),潮南網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。Num01–>迭代器
對(duì)于list、string、tuple、dict等這些容器對(duì)象,使用for循環(huán)遍歷是很方便的。在后臺(tái)for語(yǔ)句對(duì)容器對(duì)象調(diào)用iter()
函數(shù)。iter()
是python內(nèi)置函數(shù)。
iter()
函數(shù)會(huì)返回一個(gè)定義了next()
方法的迭代器對(duì)象,它在容器中逐個(gè)訪問(wèn)容器內(nèi)的元素。next()
也是python內(nèi)置函數(shù)。在沒(méi)有后續(xù)元素時(shí),next()
會(huì)拋出一個(gè)StopIteration異常,通知for語(yǔ)句循環(huán)結(jié)束。
迭代器是用來(lái)幫助我們記錄每次迭代訪問(wèn)到的位置,當(dāng)我們對(duì)迭代器使用next()函數(shù)的時(shí)候,迭代器會(huì)向我們返回它所記錄位置的下一個(gè)位置的數(shù)據(jù)。實(shí)際上,在使用next()
函數(shù)的時(shí)候,調(diào)用的就是迭代器對(duì)象的_next_方法(Python3中是對(duì)象的_next_方法,Python2中是對(duì)象的next()
方法)。所以,我們要想構(gòu)造一個(gè)迭代器,就要實(shí)現(xiàn)它的_next_方法。但這還不夠,python要求迭代器本身也是可迭代的,所以我們還要為迭代器實(shí)現(xiàn)_iter_方法,而_iter_方法要返回一個(gè)迭代器,迭代器自身正是一個(gè)迭代器,所以迭代器的_iter_方法返回自身self即可。
1,迭代器協(xié)議:對(duì)象需要提供next()
方法,它要么返回迭代中的下一項(xiàng),要么就引起一個(gè)StopIteration異常,以終止迭代。
2,可迭代對(duì)象:實(shí)現(xiàn)了迭代器協(xié)議對(duì)象。list、tuple、dict都是Iterable(可迭代對(duì)象),但不是Iterator(迭代器對(duì)象)。但可以使用內(nèi)建函數(shù)iter()
,把這些都變成Iterable(可迭代器對(duì)象)。
3,for item in Iterable 循環(huán)的本質(zhì)就是先通過(guò)iter()
函數(shù)獲取可迭代對(duì)象Iterable的迭代器,然后對(duì)獲取到的迭代器不斷調(diào)用next()
方法來(lái)獲取下一個(gè)值并將其賦值給item,當(dāng)遇到StopIteration的異常后循環(huán)結(jié)束
# 隨便定義一個(gè)list listArray=[1,2,3] # 使用iter()函數(shù) iterName=iter(listArray) print(iterName) # 結(jié)果如下:是一個(gè)列表list的迭代器 #print(next(iterName)) print(next(iterName)) print(next(iterName)) print(next(iterName))#沒(méi)有迭代到下一個(gè)元素,直接拋出異常 # 1 # 2 # 3 # Traceback (most recent call last): # File "Test07.py", line 32, in # StopIteration
Python中一個(gè)實(shí)現(xiàn)了_iter_方法和_next_方法的類對(duì)象,就是迭代器,如下案例是計(jì)算菲波那切數(shù)列的案例
class Fib(object): def __init__(self, max): super(Fib, self).__init__() self.max = max def __iter__(self): self.a = 0 self.b = 1 return self def __next__(self): fib = self.a if fib > self.max: raise StopIteration self.a, self.b = self.b, self.a + self.b return fib # 定義一個(gè)main函數(shù),循環(huán)遍歷每一個(gè)菲波那切數(shù) def main(): # 20以內(nèi)的數(shù) fib = Fib(20) for i in fib: print(i) # 測(cè)試 if __name__ == '__main__': main()
解釋說(shuō)明:
在本類的實(shí)現(xiàn)中,定義了一個(gè)_iter_(self)
方法,這個(gè)方法是在for循環(huán)遍歷時(shí)被iter()調(diào)用,返回一個(gè)迭代器。因?yàn)樵诒闅v的時(shí)候,是直接調(diào)用的python內(nèi)置函數(shù)iter()
,由iter()通過(guò)調(diào)用_iter_(self)
獲得對(duì)象的迭代器。有了迭代器,就可以逐個(gè)遍歷元素了。而逐個(gè)遍歷的時(shí)候,也是使用內(nèi)置的next()函數(shù)通過(guò)調(diào)用對(duì)象的_next_(self)
方法對(duì)迭代器對(duì)象進(jìn)行遍歷。所以要實(shí)現(xiàn)_iter_(self)
和_next_(self)
這兩個(gè)方法。
而且因?yàn)閷?shí)現(xiàn)了_next_(self)
方法,所以在實(shí)現(xiàn)_iter_(self)
的時(shí)候,直接返回self就可以。
總結(jié)一句話就是:
在循環(huán)遍歷自定義容器對(duì)象時(shí),會(huì)使用python內(nèi)置函數(shù)iter()
調(diào)用遍歷對(duì)象的_iter_(self)
獲得一個(gè)迭代器,之后再循環(huán)對(duì)這個(gè)迭代器使用next()
調(diào)用迭代器對(duì)象的_next_(self)
。
注意點(diǎn): _iter_(self)
只會(huì)被調(diào)用一次,而_next_(self)
會(huì)被調(diào)用 n 次,直到出現(xiàn)StopIteration異常。
>延遲操作。也就是在需要的時(shí)候才產(chǎn)生結(jié)果,不是立即產(chǎn)生結(jié)果。
>生成器是只能遍歷一次的。
>生成器是一類特殊的迭代器。
第一類:生成器函數(shù):還是使用 def 定義函數(shù),但是,使用yield而不是return語(yǔ)句返回結(jié)果。yield語(yǔ)句一次返回一個(gè)結(jié)果,在每個(gè)結(jié)果中間,掛起函數(shù)的狀態(tài),以便下次從它離開(kāi)的地方繼續(xù)執(zhí)行。
如下案例加以說(shuō)明:
# 菲波那切數(shù)列 def Fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return '親!沒(méi)有數(shù)據(jù)了...' # 調(diào)用方法,生成出10個(gè)數(shù)來(lái) f=Fib(10) # 使用一個(gè)循環(huán)捕獲最后return 返回的值,保存在異常StopIteration的value中 while True: try: x=next(f) print("f:",x) except StopIteration as e: print("生成器最后的返回值是:",e.value) break
第二類:生成器表達(dá)式:類似于列表推導(dǎo),只不過(guò)是把一對(duì)大括號(hào)[]
變換為一對(duì)小括號(hào)()
。但是,生成器表達(dá)式是按需產(chǎn)生一個(gè)生成器結(jié)果對(duì)象,要想拿到每一個(gè)元素,就需要循環(huán)遍歷。
如下案例加以說(shuō)明:
# 一個(gè)列表 xiaoke=[2,3,4,5] # 生成器generator,類似于list,但是是把[]改為() gen=(a for a in xiaoke) for i in gen: print(i) #結(jié)果是: 2 3 4 5 # 為什么要使用生成器?因?yàn)樾省?# 使用生成器表達(dá)式取代列表推導(dǎo)式可以同時(shí)節(jié)省 cpu 和 內(nèi)存(RAM)。 # 如果你構(gòu)造一個(gè)列表(list)的目的僅僅是傳遞給別的函數(shù), # 比如 傳遞給tuple()或者set(), 那就用生成器表達(dá)式替代吧! # 本案例是直接把列表轉(zhuǎn)化為元組 kk=tuple(a for a in xiaoke) print(kk) #結(jié)果是: (2, 3, 4, 5) # python內(nèi)置的一些函數(shù),可以識(shí)別這是生成器表達(dá)式,外面有一對(duì)小括號(hào),就是生成器 result1=sum(a for a in range(3)) print(result1) # 列表推導(dǎo)式 result2=sum([a for a in range(3)]) print(result2)
關(guān)于Python中生成器與迭代器有什么區(qū)別就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。