可迭代對(duì)象蚌堵、迭代器和生成器

迭代是數(shù)據(jù)處理的基石。掃描內(nèi)存中放不下的數(shù)據(jù)時(shí)沛婴,我們要找到一種惰性獲取數(shù)據(jù)項(xiàng)的方式吼畏,即按需一次獲取一個(gè)數(shù)據(jù)項(xiàng),這就是迭代器模式嘁灯。

在python語(yǔ)言內(nèi)部泻蚊,迭代器用于支持:

for 循環(huán)

構(gòu)建和擴(kuò)展集合類型

逐行遍歷文本文件

列表推導(dǎo)、字典推導(dǎo)和集合推導(dǎo)

元組拆包

調(diào)用函數(shù)時(shí)丑婿,使用*拆包實(shí)參

序列可迭代的原因:iter函數(shù)

解釋器需要迭代對(duì)象x時(shí)性雄,會(huì)自動(dòng)調(diào)用iter(x)

內(nèi)置的iter函數(shù)由以下作用。

1羹奉、檢查對(duì)象是否實(shí)現(xiàn)了__iter__方法秒旋,如果實(shí)現(xiàn)了就調(diào)用它,獲取一個(gè)迭代器诀拭。

2迁筛、如果沒(méi)有實(shí)現(xiàn)__iter__方法,但是實(shí)現(xiàn)了__getitem__方法炫加,python會(huì)創(chuàng)建一個(gè)迭代器瑰煎,嘗試按順序獲取元素。

3俗孝、如果嘗試失敗酒甸,python拋出TypeError異常,通常會(huì)提示“C object is not iterable”

可迭代的對(duì)象與迭代器的對(duì)比

可迭代的對(duì)象:

使用iter內(nèi)置函數(shù)可以獲取迭代器的對(duì)象赋铝。如果對(duì)象實(shí)現(xiàn)了能返回迭代器的__iter__方法插勤,那么對(duì)象就是可迭代的。序列都可以迭代,因?yàn)閷?shí)現(xiàn)了__getitem__方法农尖。

標(biāo)準(zhǔn)迭代器接口有兩個(gè)方法:

__next__:返回下一個(gè)可用的元素析恋,如果沒(méi)有元素了,則拋出StopIteration異常盛卡。

__iter__:返回self助隧,以便在應(yīng)該可迭代對(duì)象的地方使用迭代器。

迭代器:

迭代器時(shí)這樣的對(duì)象:實(shí)現(xiàn)了無(wú)參數(shù)的__next__方法滑沧,返回序列中的下一個(gè)元素并村,如果沒(méi)有元素了,那么拋出StopIteration異常滓技。python中的迭代器還實(shí)現(xiàn)了__iter__方法哩牍,因此迭代器也可以迭代。

典型的迭代器

下例中定義的Sentence類可以迭代令漂,因?yàn)樗鼘?shí)現(xiàn)了特殊的__iter__方法膝昆,構(gòu)建并返回一個(gè)SentenceIterator實(shí)例。


把Sentence變成迭代器:壞主意

可迭代的對(duì)象有個(gè)__iter__方法叠必,每次實(shí)例化一個(gè)新的迭代器荚孵,而迭代器要實(shí)現(xiàn)__next__方法,返回單個(gè)元素挠唆,此外還要實(shí)現(xiàn)__iter__方法处窥,返回迭代器本身嘱吗,因此玄组,迭代器可以迭代,但是可迭代對(duì)象不是迭代器谒麦。

可迭代的對(duì)象一定不能是自身的迭代器俄讹。也就是說(shuō),可迭代的對(duì)象必須實(shí)現(xiàn)__iter__方法绕德,但不能實(shí)現(xiàn)__next__方法患膛。

生成器函數(shù)

實(shí)現(xiàn)相同功能,但更符合python習(xí)慣的方式是耻蛇,用生成器函數(shù)代替SentenceIterator類踪蹬。


在上例中,迭代器其實(shí)是生成器對(duì)象臣咖,每次調(diào)用__iter__方法都會(huì)自動(dòng)創(chuàng)建跃捣,因?yàn)檫@里的__iter__方法是生成器函數(shù)。

生成器函數(shù)的工作原理

只要python函數(shù)的定義體中有yield關(guān)鍵字夺蛇,該函數(shù)就是生成器函數(shù)疚漆。調(diào)用生成器函數(shù)時(shí),會(huì)返回一個(gè)生成器對(duì)象,也就是說(shuō)娶聘,生成器函數(shù)是生成器工廠闻镶。

惰性實(shí)現(xiàn)

之前實(shí)現(xiàn)的幾版Sentence類都不具有惰性,因?yàn)開(kāi)_init__方法急迫地構(gòu)建好了文本中的單詞列表丸升,然后將其綁定到self.words屬性上铆农。這樣就得處理整個(gè)文本,列表使用的內(nèi)存量可能與文本本身一樣多狡耻。

re.finditer函數(shù)是re.findall函數(shù)的惰性版本顿涣,返回的不是列表,而是一個(gè)生成器酝豪。

生成器表達(dá)式

生成器表達(dá)式可以理解為列表推導(dǎo)的惰性版本:不會(huì)迫切地構(gòu)建列表涛碑,而是返回一個(gè)生成器,按需惰性生成元素孵淘。也就是說(shuō)蒲障,如果列表推導(dǎo)是制造列表的工廠,那么生成器表達(dá)式就是制造生成器的工廠瘫证。

下例先在列表推導(dǎo)中使用gen_AB生成器函數(shù)揉阎,然后在生成器表達(dá)式中使用



下例用生成器表達(dá)式實(shí)現(xiàn)Sentence類


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市背捌,隨后出現(xiàn)的幾起案子毙籽,更是在濱河造成了極大的恐慌,老刑警劉巖毡庆,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坑赡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡么抗,警方通過(guò)查閱死者的電腦和手機(jī)毅否,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蝇刀,“玉大人螟加,你說(shuō)我怎么就攤上這事⊥趟觯” “怎么了捆探?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)站粟。 經(jīng)常有香客問(wèn)我黍图,道長(zhǎng),這世上最難降的妖魔是什么卒蘸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任雌隅,我火速辦了婚禮翻默,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恰起。我一直安慰自己修械,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布检盼。 她就那樣靜靜地躺著肯污,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吨枉。 梳的紋絲不亂的頭發(fā)上蹦渣,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音貌亭,去河邊找鬼柬唯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛圃庭,可吹牛的內(nèi)容都是我干的锄奢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼剧腻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拘央!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起书在,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤灰伟,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后儒旬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體栏账,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年义矛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了发笔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凉翻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捻激,到底是詐尸還是另有隱情制轰,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布胞谭,位于F島的核電站垃杖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏丈屹。R本人自食惡果不足惜调俘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一伶棒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧彩库,春花似錦肤无、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至眯搭,卻和暖如春窥翩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鳞仙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工寇蚊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人棍好。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓幔荒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親梳玫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爹梁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容