Python迭代器和生成器介紹
迭代器
迭代器是一個(gè)實(shí)現(xiàn)了迭代器協(xié)議的對(duì)象,Python中的迭代器協(xié)議就是有next方法的對(duì)象會(huì)前進(jìn)到下一結(jié)果,而在一系列結(jié)果的末尾是,則會(huì)引發(fā)StopIteration。

在for循環(huán)中,Python將自動(dòng)調(diào)用工廠函數(shù)iter()獲得迭代器,自動(dòng)調(diào)用next()獲取元素,還完成了檢查StopIteration異常的工作。

常用的幾個(gè)內(nèi)建數(shù)據(jù)結(jié)構(gòu)tuple、list、set、dict都支持迭代器,字符串也可以使用迭代操作。
你也可以自己實(shí)現(xiàn)一個(gè)迭代器,如上所述,只需要在類(lèi)的__iter__方法中返回一個(gè)對(duì)象,這個(gè)對(duì)象擁有一個(gè)next()方法,這個(gè)方法能在恰當(dāng)?shù)臅r(shí)候拋出StopIteration異常即可。但是需要自己實(shí)現(xiàn)迭代器的時(shí)候不多,即使需要,使用生成器會(huì)更輕松。
#!/usr/bin/env python
# coding=utf-8
class test:
def __init__(self, input_list):
self.list = input_list
self.i = 0
def __iter__(self):
return self
def next(self):
if self.i == len(self.list):
self.i = 0
raise StopIteration
self.i += 1
return self.list[self.i - 1]

使用迭代器一個(gè)顯而易見(jiàn)的好處就是:每次只從對(duì)象中讀取一條數(shù)據(jù),不會(huì)造成內(nèi)存的過(guò)大開(kāi)銷(xiāo)。
例如:
/* 把文件一次加載到內(nèi)存中,然后逐行打印。當(dāng)文件很大時(shí),這個(gè)方法的內(nèi)存開(kāi)銷(xiāo)就很大了 */
for line in open("test.txt").readlines():
print line
/* 這是最簡(jiǎn)單也是運(yùn)行速度最快的寫(xiě)法,他并沒(méi)顯式的讀取文件,而是利用迭代器每次讀取下一行 */
for line in open("test.txt"): #use file iterators
print line
生成器
生成器的編寫(xiě)方法和函數(shù)定義類(lèi)似,只是在return的地方改為yield。
生成器中可以有多個(gè)yield。當(dāng)生成器遇到一個(gè)yield時(shí),會(huì)暫停運(yùn)行生成器,返回yield后面的值。當(dāng)再次調(diào)用生成器的時(shí)候,會(huì)從剛才暫停的地方繼續(xù)運(yùn)行,直到下一個(gè)yield。
生成器自身又構(gòu)成一個(gè)迭代器,每次迭代時(shí)使用一個(gè)yield返回的值。

需要注意的是,生成器中不需要return語(yǔ)句,不需要指定返回值,在生成器中已經(jīng)存在默認(rèn)的返回語(yǔ)句
生成器表達(dá)式
(i for i in range(5))
// 返回迭代器
<generator object <genexpr> at 0x7ff3e8f0d960>
列表解析,返回list
[i for i in range(5)]
// 返回list
[0, 1, 2, 3, 4]
在這里存在一個(gè)問(wèn)題,那就是range(5)會(huì)返回一個(gè)長(zhǎng)度為5的數(shù)據(jù),如果是range(1000)那么就會(huì)占用一個(gè)1000大小的數(shù)組空間;如果我們采用`生成器`,在需要的時(shí)候產(chǎn)生一個(gè)數(shù)字,那么空間的占用情況就會(huì)降低,這里我們可以使用xrange()函數(shù)來(lái)實(shí)現(xiàn)。
'''
xrange
函數(shù)說(shuō)明:用法與range完全相同,所不同的是生成的不是一個(gè)數(shù)組,而是一個(gè)生成器。
xrange示例:
'''
>>> xrange(5)
xrange(5)
>>> list(xrange(5))
[0, 1, 2, 3, 4]
>>> xrange(1,5)
xrange(1, 5)
>>> list(xrange(1,5))
[1, 2, 3, 4]
>>> xrange(0,6,2)
xrange(0, 6, 2)
>>> list(xrange(0,6,2))
[0, 2, 4]
所以xrange做循環(huán)的性能比range好,尤其是返回很大的時(shí)候,盡量用xrange吧,除非你是要返回一個(gè)列表。
相關(guān)文章
Python使用鄰接矩陣實(shí)現(xiàn)圖及Dijkstra算法問(wèn)題
這篇文章主要介紹了Python使用鄰接矩陣實(shí)現(xiàn)圖及Dijkstra算法問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
Python第三方包之DingDingBot釘釘機(jī)器人
這篇文章主要介紹了Python第三方包之DingDingBot釘釘機(jī)器人,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
在Django框架中運(yùn)行Python應(yīng)用全攻略
這篇文章主要介紹了在Django框架中運(yùn)行Python應(yīng)用全攻略,在這之前必須搭建好簡(jiǎn)單的視圖和模版,接下來(lái)便是本文中所述的核心內(nèi)容應(yīng)用配置,需要的朋友可以參考下2015-07-07
anaconda升級(jí)sklearn版本的實(shí)現(xiàn)方法
這篇文章主要介紹了anaconda升級(jí)sklearn版本的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
在Django下創(chuàng)建項(xiàng)目以及設(shè)置settings.py教程
今天小編就為大家分享一篇在Django下創(chuàng)建項(xiàng)目以及設(shè)置settings.py教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
Python中對(duì)象的比較操作==和is區(qū)別詳析
這篇文章主要給大家介紹了關(guān)于Python中對(duì)象的比較操作==和is區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
Python使用Transformers實(shí)現(xiàn)機(jī)器翻譯功能
近年來(lái),機(jī)器翻譯技術(shù)飛速發(fā)展,從傳統(tǒng)的基于規(guī)則的翻譯到統(tǒng)計(jì)機(jī)器翻譯,再到如今流行的神經(jīng)網(wǎng)絡(luò)翻譯模型,尤其是基于Transformer架構(gòu)的模型,翻譯效果已經(jīng)有了質(zhì)的飛躍,本文將詳細(xì)介紹如何使用Transformers庫(kù)來(lái)實(shí)現(xiàn)一個(gè)機(jī)器翻譯模型,需要的朋友可以參考下2024-11-11
淺談spring boot 集成 log4j 解決與logback沖突的問(wèn)題
今天小編就為大家分享一篇淺談spring boot 集成 log4j 解決與logback沖突的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
Flask框架中密碼的加鹽哈希加密和驗(yàn)證功能的用法詳解
加鹽加密就是在加密時(shí)混入一段隨機(jī)字符串,這段字符串便被稱(chēng)為"鹽值",這里我們來(lái)看一下Python的Flask框架中密碼的加鹽哈希加密和驗(yàn)證功能的用法詳解:2016-06-06

