国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python編程中實(shí)現(xiàn)迭代器的一些技巧小結(jié)

2019-11-25 16:42:34
字體:
供稿:網(wǎng)友

yield實(shí)現(xiàn)迭代器
如引言中的描述,實(shí)現(xiàn)一個(gè)可迭代的功能要是每次都手動(dòng)實(shí)現(xiàn)iter,next稍稍有點(diǎn)麻煩,所需的代碼也是比較客觀。在python中也能通過借助yield的方式來實(shí)現(xiàn)一個(gè)迭代器。yield有一個(gè)關(guān)鍵的作能,它能夠中斷當(dāng)前的執(zhí)行邏輯,保持住現(xiàn)場(chǎng)(各種值的狀態(tài),執(zhí)行的位置等等),返回相應(yīng)的值,下一次執(zhí)行的時(shí)候能夠無縫的接著上次的地方繼續(xù)執(zhí)行,如此循環(huán)反復(fù)知道滿足事先設(shè)置的退出條件或者發(fā)生錯(cuò)誤強(qiáng)制被中斷。
其具體功能是可以當(dāng)return使用,從函數(shù)里返回一個(gè)值,不同之處是用yield返回之后,可以讓函數(shù)從上回yield返回的地點(diǎn)繼續(xù)執(zhí)行。也就是說,yield返回函數(shù),交給調(diào)用者一個(gè)返回值,然后再“瞬移”回去,讓函數(shù)繼續(xù)運(yùn)行, 直到嚇一跳yield語句再返回一個(gè)新的值。使用yield返回后,調(diào)用者實(shí)際得到的是一個(gè)迭代器對(duì)象,迭代器的值就是返回值,而調(diào)用該迭代器的next()方法會(huì)導(dǎo)致該函數(shù)恢復(fù)yield語句的執(zhí)行環(huán)境繼續(xù)往下跑,直到遇到下一個(gè)yield為止,如果遇不到y(tǒng)ield,就會(huì)拋出異常表示迭代結(jié)束。
看一個(gè)例子:

>>> def test_yield():... yield 1... yield 2... yield (1,2)...>>> a = test_yield()>>> a.next()1>>> a.next()2>>> a.next()(1, 2)>>> a.next()Traceback (most recent call last): File "<stdin>", line 1, in ?StopIteration

光聽描述就覺得和迭代器的工作方式很一致是吧,的確,yield能把它所在的函索變成一個(gè)迭代器,拿最經(jīng)典的菲波那切數(shù)列的例子聊簡(jiǎn)述一下工作的方式:

def fab(max):  n, a, b = 0, 0, 1  while n < max: print b, "is generated"  yield b a, b = b, a + b  n = n + 1 >>> for item in fab(5):... print item... 1 is generated11 is generated12 is generated23 is generated35 is generated5

我們有回想一下for關(guān)鍵字的語法糖,在這里遍歷5以內(nèi)的菲波那切數(shù)列值的時(shí)候,很顯然fab(5)生成了一個(gè)可迭代的對(duì)象,遍歷開始的時(shí)候它的iter方法被調(diào)用返回一個(gè)實(shí)際工作的迭代器對(duì)象,然后每一次調(diào)用它的next方法返回一個(gè)菲波那切數(shù)列值然后打印出來。
我們可以將調(diào)用生成器函數(shù)返回的對(duì)象的屬性打印出來,看一下到底發(fā)生了什么:

>>> temp_gen = fab(5)>>> dir(temp_gen)['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']

正如上面的描述,單純調(diào)用fab并不會(huì)讓函數(shù)立刻開始返回任何值,并且從打印出的fab(5)的屬性列表能夠看到,生成器函數(shù)返回的對(duì)象包含有__iter__,next的實(shí)現(xiàn)。與我們手動(dòng)實(shí)現(xiàn)相比,使用yield很方便的就能夠?qū)崿F(xiàn)我們想要的功能,代碼量縮減不少。

Generator Expression
python中另一種能更優(yōu)雅生成迭代器對(duì)象的方式就是使用生成器表達(dá)式Generator expression,它和列表解析表達(dá)式有著非常相似的寫法,僅僅是把中括號(hào)[]變成()而已,不過小小改變產(chǎn)生的實(shí)際效果確實(shí)大大的不一樣:

>>> temp_gen = (x for x in range(5))>>> temp_gen<generator object <genexpr> at 0x7192d8>>>> for item in temp_gen:... print item... 01234>>> dir(temp_gen)['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']

看過上面對(duì)yield的描述,這個(gè)例子以及對(duì)應(yīng)的輸出日志還是相當(dāng)直接明了的,無論是temp_gen的打印日志描述,for語句遍歷的輸出結(jié)果還是調(diào)用dir輸出的屬性列表,都赤裸裸的表明生成器表達(dá)式確實(shí)生成了能夠支持迭代的對(duì)象。另外表達(dá)式里面也能夠調(diào)用函數(shù),增加適量的過濾條件。

內(nèi)置庫itertools 和 iter
python內(nèi)置的庫itertools提供了大量的工具方法,這些方法能夠幫助我們創(chuàng)建能進(jìn)行高效遍歷和迭代的對(duì)象,里面包含不少有意思并且有用的方法,比如像chain, izip/izip_longest, combinations, ifilter等等。在python中還有一個(gè)內(nèi)置的iter函數(shù)非常有用,能夠返回一個(gè)迭代器對(duì)象,之后也就能夠進(jìn)行可以查看對(duì)應(yīng)的幫助文檔簡(jiǎn)單看一下:

>>> iter('abc')<iterator object at 0x718590>>>> str_iterator = iter('abc')>>> next(str_iterator)'a'>>> next(str_iterator)'b'>>> lst_gen = iter([1,2,3,4])>>> lst_gen<listiterator object at 0x728e30>>>> dir(lst_gen)['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__length_hint__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'next']>>> help(iter)Help on built-in function iter in module builtins:iter(...) iter(iterable) -> iterator iter(callable, sentinel) -> iterator Get an iterator from an object. In the first form, the argument must supply its own iterator, or be a sequence. In the second form, the callable is called until it returns the sentinel.
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 拜泉县| 二手房| 林甸县| 麻城市| 泾阳县| 松桃| 辽阳县| 榆树市| 伊吾县| 连州市| 崇礼县| 武山县| 调兵山市| 祁东县| 通化县| 慈利县| 阜康市| 台南县| 敦化市| 平原县| 哈密市| 乐东| 论坛| 米易县| 澎湖县| 嘉祥县| 铁岭县| 晴隆县| 新干县| 呼图壁县| 桂林市| 东乌珠穆沁旗| 湘阴县| 白水县| 通辽市| 章丘市| 龙江县| 科技| 天全县| 镇康县| 宣恩县|