摘要:本文重點(diǎn)掌握可迭代的對(duì)象的定義掌握可迭代對(duì)象迭代器與生成器之間的關(guān)系和異同熟悉標(biāo)準(zhǔn)庫中生成器。二迭代器迭代器介紹迭代器用于從集合中取出元素的對(duì)象。若想再次迭代須重建迭代器。迭代器檢查方式調(diào)用,。區(qū)別可迭代的對(duì)象不是迭代器。
導(dǎo)語:本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之控制流程篇的重點(diǎn)知識(shí)及個(gè)人心得,打算入門Python的朋友們可以來一起學(xué)習(xí)并交流。
本文重點(diǎn):
1、掌握可迭代的對(duì)象的定義;一、可迭代的對(duì)象
2、掌握可迭代對(duì)象、迭代器與生成器之間的關(guān)系和異同;
3、熟悉標(biāo)準(zhǔn)庫中生成器。
可迭代的對(duì)象:使用iter內(nèi)置函數(shù)可以獲取迭代器的對(duì)象。如果對(duì)象實(shí)現(xiàn)了能返回迭代器的__iter__方法,那么對(duì)象就是可迭代的。如果沒有實(shí)現(xiàn)__iter__而實(shí)現(xiàn)了__getitem__方法,并且其參數(shù)是從零開始的索引,這種對(duì)象如序列也是可迭代的。
向后兼容:之所以任何Python序列可迭代是為了向后兼容。
當(dāng)解釋器需要迭代對(duì)象時(shí),會(huì)自動(dòng)調(diào)用iter(x):
若對(duì)象實(shí)現(xiàn)了__iter__方法,獲取一個(gè)迭代器;
若對(duì)象沒實(shí)現(xiàn)__iter__方法,但實(shí)現(xiàn)了__getitem__方法,Python會(huì)創(chuàng)建一個(gè)迭代器,嘗試從索引0開始獲取元素;
若嘗試失敗,Python拋出TypeError。
標(biāo)準(zhǔn)的序列都實(shí)現(xiàn)了__iter__方法,這是鴨子類型的極端形式。
在白鵝類型中,只要對(duì)象實(shí)現(xiàn)了__iter__方法,那么它就是可迭代的對(duì)象。
注意:
(1)只有實(shí)現(xiàn)了__iter__方法的對(duì)象能通過子類測(cè)試issubclass(Object,abc.Iterator)
(2)檢查對(duì)象能否迭代最準(zhǔn)確的方法是調(diào)用iter(x)函數(shù),如果不可迭代再處理TypeError。因?yàn)閕ter(x)會(huì)考慮到實(shí)現(xiàn)__getitem__方法的部分可迭代對(duì)象。
迭代器:用于從集合中取出元素的對(duì)象。
迭代器的功能:用于支持下列操作
for循環(huán)
構(gòu)建和擴(kuò)展集合類型
逐行遍歷文本文件
列表推導(dǎo)、字典推導(dǎo)和集合推導(dǎo)
元組拆包
調(diào)用函數(shù)時(shí),使用 * 拆包實(shí)參
迭代器的接口協(xié)議:
__next__,返回下一個(gè)可用的元素。當(dāng)沒有元素時(shí)拋出StopIteration異常。
__iter__,返回self,即迭代器本身。
迭代器特點(diǎn):
可迭代。由于Python中的迭代器實(shí)現(xiàn)了__iter__方法,因此也可以迭代。
易耗損。迭代器經(jīng)過一次逐次取值的循環(huán)后便耗盡了。若想再次迭代須重建迭代器。
迭代器檢查方式:調(diào)用isinstance(object,abc.Iterator)。
檢查原理:歸結(jié)于Iterator.__subclasshook__方法。無論對(duì)象所屬的類是Iterator的真實(shí)子類還是虛擬子類,都能夠檢查。
聯(lián)系:Python從可迭代的對(duì)象中獲取迭代器。
區(qū)別:可迭代的對(duì)象不是迭代器。
3、迭代器模式迭代器模式:按需一次獲取一個(gè)數(shù)據(jù)項(xiàng)。
掃描內(nèi)存中放不下的數(shù)據(jù)集時(shí),我們要找到一種惰性獲取數(shù)據(jù)項(xiàng)的方式,即按需一次獲取一個(gè)數(shù)據(jù)項(xiàng)。這就是迭代器模式(Iterator pattern) 。
迭代器模式的用途:
訪問一個(gè)聚合對(duì)象的內(nèi)容而無需暴露它的內(nèi)部表示;
支持對(duì)聚合對(duì)象的多種遍歷;
為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口(即支持多態(tài)迭代)。
4、迭代器模式實(shí)例下面構(gòu)造一個(gè)可以處理文本匹配并迭代的實(shí)例:
import reprlib import re reword=re.compile("w+") #第一版:迭代器模式 class Sentence: def __init__(self,text): self.text=text self.words=reword.findall(text) def __repr__(self): return "Sentence({})".format(reprlib.repr(self.text)) def __iter__(self): return SentenceIterator(self.words) class SentenceIterator: def __init__(self,text): self.words=text self.index=0 def __next__(self): try: word=self.words[self.index] except IndexError: raise StopIteration() self.index += 1 return word def __iter__(self): return self title=Sentence("We have a dream!") print(title) for i in title: print(i)
輸出: Sentence("We have a dream!") We have a dream
注意:
(1)不要把迭代器接口應(yīng)用到可迭代對(duì)象上,這是常見的反模式。
(2)可迭代對(duì)象必須實(shí)現(xiàn)__iter__方法,但不能實(shí)現(xiàn)__next__方法。
生成器:用于按需生成元素的對(duì)象。在Python社區(qū)中大多數(shù)時(shí)候都把迭代器和生成器視作同一概念。
生成器函數(shù):擁有yield關(guān)鍵字的Python函數(shù)。
生成器表達(dá)式:制造生成器的工廠,支持惰性產(chǎn)值。
生成器工廠函數(shù):返回生成器的函數(shù),定義體中可以沒有yield關(guān)鍵字。
生成器函數(shù)與生成器表達(dá)式優(yōu)點(diǎn)比較:
生成器函數(shù):使用重復(fù)使用的情景,也可以作為協(xié)程使用。
生成器表達(dá)式:代碼簡(jiǎn)潔易讀。
Tips:生成器表達(dá)式作為單參數(shù)傳入時(shí)無須寫一對(duì)括號(hào),而多參數(shù)時(shí)須將小括號(hào)加上。
2、生成器函數(shù)工作原理實(shí)例1:通過一個(gè)問候同學(xué)的代碼來了解生成器函數(shù)是如何工作的
def gen(): print("start") yield "Jack" print("continue") yield "Dennis" print("end") for i in gen(): print("Hello ",i)
輸出: start Hello Jack continue Hello Dennis end
原理分析:不難發(fā)現(xiàn),for循環(huán)中操作的對(duì)象是生成器中的yield生成的值。原因在于,生成器是迭代器,會(huì)生成傳給yield關(guān)鍵字的表達(dá)式的值。
注意:不管有沒有return語句,生成器函數(shù)都不會(huì)拋出StopIteration異常,而是在生成全部值之后直接退出。
實(shí)例2:生成器函數(shù)改進(jìn)版
import reprlib import re reword=re.compile("w+") #第二版:生成器函數(shù) class Sentence: def __init__(self,text): self.text=text self.words=reword.findall(text) def __repr__(self): return "Sentence({})".format(reprlib.repr(self.text)) def __iter__(self): for i in self.words: yield i return title=Sentence("We have a dream!") print(title) for i in title: print(i)3、惰性產(chǎn)值:生成器表達(dá)式模式改進(jìn)版
import reprlib import re reword=re.compile("w+") #第三版:生成器表達(dá)式 class Sentence: def __init__(self,text): self.text=text def __repr__(self): return "Sentence({})".format(reprlib.repr(self.text)) def __iter__(self): return (match.group() for match in reword.finditer(self.text)) title=Sentence("We have a dream!") print(title) for i in title: print(i)
Tips:re.finditer函數(shù)是re.findall函數(shù)的惰性版本,返回的不是列表而是一個(gè)生成器,按需惰性生成元素。
四、標(biāo)準(zhǔn)庫中有用的生成器 1、五大類生成器用于過濾的生成器函數(shù): itertools.takewhile/compress/dropwhile/filter/filterfalse/islice/
用于映射的生成器函數(shù): 內(nèi)置的 enumerate/map itertools.accumulate/starmap
用于合并的生成器函數(shù):itertools.chain/from_iterable/product/zip_longest/ 內(nèi)置的 zip
從一個(gè)元素產(chǎn)生多個(gè)值,擴(kuò)展輸入的可迭代對(duì)象: itertools.combinations/combinations_with_replacement/count/cycle/permutations/repeat
產(chǎn)出輸入可迭代對(duì)象的全部元素,以某種方式排列:itertools.groupby/tee/ 內(nèi)置的 reversed
五、其它1、歸約函數(shù):接受可迭代對(duì)象并返回單個(gè)結(jié)果的函數(shù)。
這里的all和any函數(shù)會(huì)短路,即一旦得出結(jié)果馬上停止迭代。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/44563.html
摘要:可迭代的對(duì)象迭代器和生成器理念迭代是數(shù)據(jù)處理的基石??傻膶?duì)象與迭代器的對(duì)比從可迭代的對(duì)象中獲取迭代器標(biāo)準(zhǔn)的迭代器接口有兩個(gè)方法。此外,也沒有辦法還原迭代器。最終,函數(shù)的定義體返回時(shí),外層的生成器對(duì)象會(huì)拋出異常這一點(diǎn)與迭代器協(xié)議一致。 可迭代的對(duì)象、迭代器和生成器 理念 迭代是數(shù)據(jù)處理的基石。掃描內(nèi)存中放不下的數(shù)據(jù)集時(shí),我們要找到一種惰性獲取數(shù)據(jù)項(xiàng)的方式,即按需一次獲取一個(gè)數(shù)據(jù)項(xiàng)。這...
摘要:來說說迭代器和生成器,還有可迭代對(duì)象和生成器表達(dá)式。有點(diǎn)繞是不是,其實(shí),一般只要知道可迭代對(duì)象以及它是如何實(shí)現(xiàn)的就行了,中常常用生成器來代替迭代器,可以說,生成器就是迭代器。 來說說迭代器和生成器,還有可迭代對(duì)象和生成器表達(dá)式。 之前簡(jiǎn)單的提到過,一個(gè)對(duì)象是可迭代的可以理解為能夠使用for循環(huán)。這樣說其實(shí)不太準(zhǔn)確,某個(gè)對(duì)象可迭代是因?yàn)樗鼉?nèi)部實(shí)現(xiàn)了$__iter__$這個(gè)特殊方法。比如在...
摘要:滿足以上要求的對(duì)象,就是迭代器。其中,必需返回一個(gè)迭代器對(duì)象,則負(fù)責(zé)迭代邏輯并在迭代完畢時(shí)觸發(fā)異常。可以在遍歷迭代器的時(shí)候,加入一個(gè)判斷語句,避免無法多次迭代的情況發(fā)生參考資料官網(wǎng)迭代器文檔 什么是迭代器 相關(guān)概念定義 迭代器(Iterator): 滿足迭代協(xié)議的對(duì)象就是迭代器 iterator就是實(shí)現(xiàn)了Iteration Protocol的對(duì)象,這類對(duì)象都支持循環(huán)遍歷的操作(for...
摘要:迭代器迭代器用于循環(huán)構(gòu)建和擴(kuò)展集合類型逐行遍歷文本文件列表推導(dǎo)字典推導(dǎo)和集合推導(dǎo)元組拆包調(diào)用函數(shù)時(shí),使用拆包實(shí)參解釋器需要迭代對(duì)象時(shí),會(huì)自動(dòng)調(diào)用內(nèi)置的函數(shù),有以下功能檢查對(duì)象是否實(shí)現(xiàn)了方法,如果實(shí)現(xiàn)了就調(diào)用它,獲取一個(gè)迭代器。 迭代器 迭代器用于: for 循環(huán) 構(gòu)建和擴(kuò)展集合類型 逐行遍歷文本文件 列表推導(dǎo)、 字典推導(dǎo)和集合推導(dǎo) 元組拆包 調(diào)用函數(shù)時(shí), 使用 * 拆包實(shí)參 解釋器...
摘要:例如,以下對(duì)兩個(gè)的相應(yīng)元素求和這個(gè)例子很好的解釋了如何構(gòu)建中所謂的迭代器代數(shù)的函數(shù)的含義。為簡(jiǎn)單起見,假設(shè)輸入的長(zhǎng)度可被整除。接受兩個(gè)參數(shù)一個(gè)可迭代的正整數(shù)最終會(huì)在中個(gè)元素的所有組合的元組上產(chǎn)生一個(gè)迭代器。 前言 大家好,今天想和大家分享一下我的itertools學(xué)習(xí)體驗(yàn)及心得,itertools是一個(gè)Python的自帶庫,內(nèi)含多種非常實(shí)用的方法,我簡(jiǎn)單學(xué)習(xí)了一下,發(fā)現(xiàn)可以大大提升工作...
閱讀 1559·2021-09-22 15:35
閱讀 2035·2021-09-14 18:04
閱讀 918·2019-08-30 15:55
閱讀 2480·2019-08-30 15:53
閱讀 2709·2019-08-30 12:45
閱讀 1228·2019-08-29 17:01
閱讀 2604·2019-08-29 15:30
閱讀 3535·2019-08-29 15:09