摘要:滿足以上要求的對(duì)象,就是迭代器。其中,必需返回一個(gè)迭代器對(duì)象,則負(fù)責(zé)迭代邏輯并在迭代完畢時(shí)觸發(fā)異常??梢栽诒闅v迭代器的時(shí)候,加入一個(gè)判斷語句,避免無法多次迭代的情況發(fā)生參考資料官網(wǎng)迭代器文檔
什么是迭代器 相關(guān)概念定義 迭代器(Iterator):
滿足迭代協(xié)議的對(duì)象就是迭代器
iterator就是實(shí)現(xiàn)了Iteration Protocol的對(duì)象,這類對(duì)象都支持循環(huán)遍歷的操作(for/while/支持迭代的函數(shù)list() sum()...)。
內(nèi)建函數(shù)iter()接收一個(gè)可迭代對(duì)象,并返回一個(gè)可迭代對(duì)象.
每次將這個(gè)可迭代對(duì)象傳遞給next()函數(shù),都會(huì)返回它所包含的下一個(gè)元素,當(dāng)?shù)曜詈笠粋€(gè)元素時(shí),就會(huì)觸發(fā)StopIteration異常。
>>> x = iter([1, 2, 3]) >>> x>>> next(x) 1 >>> next(x) 2 >>> next(x) 3 >>> next(x) Traceback (most recent call last): File " ", line 1, in StopIteration
滿足以上要求的對(duì)象,就是迭代器。
迭代隱含的操作在每次的迭代語句中,python都會(huì)按照迭代協(xié)議去對(duì)迭代器進(jìn)行迭代。其實(shí),在實(shí)際執(zhí)行中,python會(huì)進(jìn)行一些其他的操作:
將需要迭代的對(duì)象作為參數(shù)傳遞給iter函數(shù)
iter返回一個(gè)迭代器對(duì)象
每次循環(huán)則將返回的迭代器對(duì)象傳遞給next函數(shù)
循環(huán)至最后一個(gè)元素,觸發(fā)StopIteration
以for語句為例:
當(dāng)我們?cè)赑ython中執(zhí)行循環(huán)語句for i in foo的時(shí)候,其背后的操作是:
foo = iter(foo)
next(foo)
next(foo)在python3中執(zhí)行的是:foo.__next__(),在python2中則是:foo.next()
迭代器的實(shí)現(xiàn)迭代器是用class來實(shí)現(xiàn)的。其中必需實(shí)現(xiàn)的有兩個(gè)方法:__iter__、next(python2)/__next__(python3)。其中,__iter__必需返回一個(gè)迭代器對(duì)象,next則負(fù)責(zé)迭代邏輯并在迭代完畢時(shí)觸發(fā)異常。
如下:
def Iter(object) def __init__(self): pass def __iter__(self): pass def __next__(self): # python3 pass def next(self): # python2 pass
迭代器的__iter__方法需要返回的是一個(gè)具有next方法的可迭代對(duì)象。如果當(dāng)__iter__返回的是self的話,就會(huì)產(chǎn)生其他意想不到的效果。
class yrange: def __init__(self, n): self.i = 0 self.n = n def __iter__(self): return self def next(self): if self.i < self.n: i = self.i self.i += 1 return i else: raise StopIteration() class zrange: def __init__(self, n): self.i = 0 self.n = n def __iter__(self): return zrange(self.n) def next(self): if self.i < self.n: i = self.i self.i += 1 return i else: raise StopIteration()
執(zhí)行結(jié)果:
>>> y = yrange(5) >>> list(y) [0, 1, 2, 3, 4] >>> list(y) [] >>> z = zrange(5) >>> list(z) [0, 1, 2, 3, 4] >>> list(z) [0, 1, 2, 3, 4]
在yrange中,iter返回的是self,在執(zhí)行list(y)時(shí)iter返回的都是同一個(gè)self,所以再次調(diào)用list(y)時(shí)只會(huì)觸發(fā)結(jié)束迭代異常,列表中并無內(nèi)容。
而在zrange中,每次執(zhí)行list(z)時(shí),iter都是返回一個(gè)新的迭代器zrange(self.n),所以每次執(zhí)行list(z)都得到完整的元素。
通常,對(duì)于數(shù)據(jù)量特別大的序列,我們會(huì)用生成器generator來代替容器對(duì)象container,這樣可以利用lazy evaluable來節(jié)省內(nèi)存開銷。值得注意的是,生成器也是一個(gè)只能迭代一次的迭代器。
def grange(n): i = 0 while i < n: yield i i += 1
執(zhí)行結(jié)果:
>>> glist = grange(10) >>> list(glist) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> list(glist) []
如果是利用便捷的生成器表達(dá)式也是一樣:
>>> alist = (i for i in range(10)) >>> list(alist) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> list(alist) []
要解決這個(gè)問題,可以將迭代器和生成器組合使用:
class Grange(object): def __init__(self, n): self.n = n def __iter__(self): for i in range(self.n): yield i
結(jié)果:
>>> glist = Grange(10) >>> list(glist) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> list(glist) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
值得注意的是,平常我們利用到生成器的地方都是數(shù)據(jù)量特別大的情況,這個(gè)時(shí)候,其實(shí)應(yīng)該盡量避免多次迭代生成器。我想這應(yīng)該也是python沒有支持對(duì)生成器多次迭代的特性的原因。
編程建議在實(shí)際的編程中,往往需要在函數(shù)中多次迭代一個(gè)序列,如果這個(gè)序列是調(diào)用API得到的,而你又不能保證它是沒有陷阱的迭代器時(shí)??梢栽诒闅v迭代器的時(shí)候,加入一個(gè)判斷語句,避免無法多次迭代的情況發(fā)生:
def iterator_checker(iterator): assert iter(iterator) is not iter(iterator), "iter() return self"參考資料
python官網(wǎng)迭代器文檔
python practice book
<
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/38062.html
摘要:迭代器對(duì)象從集合的第一個(gè)元素開始訪問,直到所有的元素被訪問完結(jié)束。迭代器有兩個(gè)基本的方法和。調(diào)用一個(gè)生成器函數(shù),返回的是一個(gè)迭代器對(duì)象。生成器函數(shù)生成器函數(shù)返回一個(gè)迭代器函數(shù)函數(shù)傳入不定長參數(shù)加了星號(hào)的變量名會(huì)存放所有未命名的變量參數(shù)。 Python學(xué)習(xí)--最完整的基礎(chǔ)知識(shí)大全 關(guān)于python的基礎(chǔ)知識(shí)學(xué)習(xí),網(wǎng)上有很多資料,今天我就把我收藏的整理一下分享給大家! 菜鳥教程pytho...
摘要:迭代器模式原文地址更多設(shè)計(jì)模式系列教程更多免費(fèi)教程博主按每天一個(gè)設(shè)計(jì)模式旨在初步領(lǐng)會(huì)設(shè)計(jì)模式的精髓,目前采用靠這吃飯和純粹喜歡兩種語言實(shí)現(xiàn)。迭代器模式常見和常用的有內(nèi)部迭代器外部迭代器倒序迭代器等等。 迭代器模式·原文地址 更多《設(shè)計(jì)模式系列教程》 更多免費(fèi)教程 博主按:《每天一個(gè)設(shè)計(jì)模式》旨在初步領(lǐng)會(huì)設(shè)計(jì)模式的精髓,目前采用javascript(靠這吃飯)和python(純粹喜歡...
摘要:迭代器模式原文地址更多設(shè)計(jì)模式系列教程更多免費(fèi)教程博主按每天一個(gè)設(shè)計(jì)模式旨在初步領(lǐng)會(huì)設(shè)計(jì)模式的精髓,目前采用靠這吃飯和純粹喜歡兩種語言實(shí)現(xiàn)。迭代器模式常見和常用的有內(nèi)部迭代器外部迭代器倒序迭代器等等。 迭代器模式·原文地址 更多《設(shè)計(jì)模式系列教程》 更多免費(fèi)教程 博主按:《每天一個(gè)設(shè)計(jì)模式》旨在初步領(lǐng)會(huì)設(shè)計(jì)模式的精髓,目前采用javascript(靠這吃飯)和python(純粹喜歡...
摘要:時(shí)間永遠(yuǎn)都過得那么快,一晃從年注冊(cè),到現(xiàn)在已經(jīng)過去了年那些被我藏在收藏夾吃灰的文章,已經(jīng)太多了,是時(shí)候把他們整理一下了。那是因?yàn)槭詹貖A太亂,橡皮擦給設(shè)置私密了,不收拾不好看呀。 ...
摘要:勤學(xué)學(xué)習(xí)效率與效果取決于執(zhí)行力。這一步學(xué)習(xí)的正確姿勢(shì)是在實(shí)踐操作中發(fā)掘問題,然后帶著問題找答案。拆分任務(wù)將目標(biāo)分解成具體可執(zhí)行的學(xué)習(xí)任務(wù)。勤學(xué)強(qiáng)大的執(zhí)行力是學(xué)習(xí)的根本保障。分享復(fù)述檢驗(yàn)學(xué)習(xí)成果,提高學(xué)習(xí)效果的最好方法。 showImg(https://segmentfault.com/img/bVbcPGZ?w=256&h=256); 前段時(shí)間和大家一起分享了一篇關(guān)于學(xué)習(xí)方法內(nèi)容《大牛...
閱讀 2092·2021-11-24 09:39
閱讀 834·2021-09-30 09:48
閱讀 1014·2021-09-22 15:29
閱讀 2451·2019-08-30 14:17
閱讀 1912·2019-08-30 13:50
閱讀 1376·2019-08-30 13:47
閱讀 1015·2019-08-30 13:19
閱讀 3446·2019-08-29 16:43