欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2016年06月21日 15:25:57   作者:TypingQuietly  
只談迭代器的話在Python中只是一個泛指的概念,具體的可以用yield、生成器表達(dá)式、iter等多種方式來構(gòu)建,這里我們整理了Python編程中實(shí)現(xiàn)迭代器的一些技巧小結(jié):

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

>>> 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能把它所在的函索變成一個迭代器,拿最經(jīng)典的菲波那切數(shù)列的例子聊簡述一下工作的方式:

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 generated
1
1 is generated
1
2 is generated
2
3 is generated
3
5 is generated
5

我們有回想一下for關(guān)鍵字的語法糖,在這里遍歷5以內(nèi)的菲波那切數(shù)列值的時候,很顯然fab(5)生成了一個可迭代的對象,遍歷開始的時候它的iter方法被調(diào)用返回一個實(shí)際工作的迭代器對象,然后每一次調(diào)用它的next方法返回一個菲波那切數(shù)列值然后打印出來。
我們可以將調(diào)用生成器函數(shù)返回的對象的屬性打印出來,看一下到底發(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并不會讓函數(shù)立刻開始返回任何值,并且從打印出的fab(5)的屬性列表能夠看到,生成器函數(shù)返回的對象包含有__iter__,next的實(shí)現(xiàn)。與我們手動實(shí)現(xiàn)相比,使用yield很方便的就能夠?qū)崿F(xiàn)我們想要的功能,代碼量縮減不少。

Generator Expression
python中另一種能更優(yōu)雅生成迭代器對象的方式就是使用生成器表達(dá)式Generator expression,它和列表解析表達(dá)式有著非常相似的寫法,僅僅是把中括號[]變成()而已,不過小小改變產(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
... 
0
1
2
3
4
>>> 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']

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

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

>>> 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.

相關(guān)文章

  • 我就是這樣學(xué)習(xí)Python中的列表

    我就是這樣學(xué)習(xí)Python中的列表

    這篇文章主要給大家介紹了關(guān)于我是如何學(xué)習(xí)Python中的列表的,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • 跟老齊學(xué)Python之正規(guī)地說一句話

    跟老齊學(xué)Python之正規(guī)地說一句話

    雖然在第一部分中,已經(jīng)零星涉及到語句問題,并且在不同場合也進(jìn)行了一些應(yīng)用。畢竟不那么系統(tǒng)。本部分,就比較系統(tǒng)地介紹python中的語句。
    2014-09-09
  • Python-openCV讀RGB通道圖實(shí)例

    Python-openCV讀RGB通道圖實(shí)例

    今天小編就為大家分享一篇Python-openCV讀RGB通道圖實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • 詳解Flask開發(fā)技巧之異常處理

    詳解Flask開發(fā)技巧之異常處理

    Flask是一個微型的Python開發(fā)的Web框架,基于Werkzeug WSGI工具箱和Jinja2 模板引擎。Flask使用BSD授權(quán)。Flask也被稱為“microframework”,因?yàn)樗褂煤唵蔚暮诵?,用extension增加其他功能。本文主要介紹了它的異常處理機(jī)制
    2021-06-06
  • python批量修改文件名的三種方法實(shí)例

    python批量修改文件名的三種方法實(shí)例

    同事最近有個需求,需要批量修改文件的名稱,這篇文章主要給大家介紹了關(guān)于python批量修改文件名的三種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • python基礎(chǔ)之序列操作

    python基礎(chǔ)之序列操作

    這篇文章主要介紹了python序列操作,實(shí)例分析了Python中返回一個返回值與多個返回值的方法,需要的朋友可以參考下
    2021-10-10
  • python?列表常用方法超詳細(xì)梳理總結(jié)

    python?列表常用方法超詳細(xì)梳理總結(jié)

    這篇文章主要為大家介紹了Python中列表的幾個常用方法總結(jié),文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Python列表有一定幫助,需要的可以參考一下
    2022-03-03
  • 用Q-learning算法實(shí)現(xiàn)自動走迷宮機(jī)器人的方法示例

    用Q-learning算法實(shí)現(xiàn)自動走迷宮機(jī)器人的方法示例

    這篇文章主要介紹了用Q-learning算法實(shí)現(xiàn)自動走迷宮機(jī)器人的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Python使用pytest-playwright的原因分析

    Python使用pytest-playwright的原因分析

    pytest-playwright 是一個 Python 包,它允許您使用 Microsoft 的 Playwright 庫在 Python 項(xiàng)目中進(jìn)行端到端測試,這篇文章主要介紹了Python為什么使用pytest-playwright,需要的朋友可以參考下
    2023-03-03
  • python初步實(shí)現(xiàn)word2vec操作

    python初步實(shí)現(xiàn)word2vec操作

    這篇文章主要介紹了python初步實(shí)現(xiàn)word2vec操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06

最新評論