亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python的迭代器和生成器

 更新時間:2015年07月29日 11:10:29   投稿:hebedich  
由于在看一個python項目,遇到了迭代器和生成器的使用,正好之前自己也沒有細看這部分,今天就稍微梳理一下吧!

先說迭代器,對于string、list、dict、tuple等這類容器對象,使用for循環(huán)遍歷是很方便的。在后臺for語句對容器對象調(diào)用iter()函數(shù),iter()是python的內(nèi)置函數(shù)。iter()會返回一個定義了next()方法的迭代器對象,它在容器中逐個訪問容器內(nèi)元素,next()也是python的內(nèi)置函數(shù)。在沒有后續(xù)元素時,next()會拋出一個StopIteration異常,通知for語句循環(huán)結(jié)束。比如:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<str_iterator object at 0x7f71fefe9d68>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

上面說的都是python自帶的容器對象,它們都實現(xiàn)了相應(yīng)的迭代器方法,那如果是自定義類需要遍歷怎么辦?方法很簡單,對這個類AClass,實現(xiàn)一個__iter__(self)方法,使其返回一個帶有__next__(self)方法的對象就可以了。如果你在AClass剛好也定義了__next__(self)方法(一般使用迭代器都會定義),那在__iter__里只要返回self就可以。廢話少說,先上代碼:

class Fib(object):
  def __init__(self, max):
    super(Fib, self).__init__()
    self.max = max

  def __iter__(self):
    self.a = 0
    self.b = 1
    return self

  def __next__(self):
    fib = self.a
    if fib > self.max:
      raise StopIteration
    self.a, self.b = self.b, self.a + self.b
    return fib

def main():
  fib = Fib(100)
  for i in fib:
    print(i)

if __name__ == '__main__':
  main()

簡單講下代碼會干什么,定義了一個Fib類,用于生成fibonacci序列。用for遍歷時會逐個打印生成的fibonacci數(shù),max是生成的fibonacci序列中數(shù)字大小的上限。

在類的實現(xiàn)中,定義了一個__iter__(self)方法,這個方法是在遍歷時被iter()調(diào)用,返回一個迭代器。因為在遍歷的時候,是直接調(diào)用的python內(nèi)置函數(shù)iter(),由iter()通過調(diào)用__iter__(self)獲得對象的迭代器。有了迭代器,就可以逐個遍歷元素了。而逐個遍歷的時候,也是使用內(nèi)置的next()函數(shù)通過調(diào)用對象的__next__(self)方法對迭代器對象進行遍歷。所以要實現(xiàn)__iter__(self)和__next__(self)。而且因為實現(xiàn)了__next__(self),所以在實現(xiàn)__iter__(self)的時候,直接返回self就可以。

為了更好理解,我再簡單重復(fù)下上面說的那一段:在循環(huán)遍歷自定義容器對象時,會使用python內(nèi)置函數(shù)iter()調(diào)用遍歷對象的__iter__(self)獲得一個迭代器,之后再循環(huán)對這個迭代器使用next()調(diào)用迭代器對象的__next__(self)。__iter__只會被調(diào)用一次,而__next__會被調(diào)用 n 次。

下面說生成器。

生成器(Generator)是創(chuàng)建迭代器的簡單而強大的工具。它們寫起來就像是正規(guī)的函數(shù),只是在需要返回數(shù)據(jù)的時候使用yield語句。每次next()被調(diào)用時,生成器會返回它脫離的位置(它記憶語句最后一次執(zhí)行的位置和所有的數(shù)據(jù)值)。以下示例演示了生成器可以很簡單的創(chuàng)建出來:

>>> def reverse(data):
...   for index in range(len(data)-1, -1, -1):
...     yield data[index]
... 
>>> for char in reverse('hello'):
...   print(char)
... 
o
l
l
e
h

關(guān)于迭代器和生成器的區(qū)別,生成器能做到迭代器能做的所有事,而且因為自動創(chuàng)建了__iter__()和 next()方法,生成器顯得特別簡潔,而且生成器也是高效的。除了創(chuàng)建和保存程序狀態(tài)的自動方法,當發(fā)生器終結(jié)時,還會自動拋出StopIteration異常。一個帶有yield的函數(shù)就是一個 生成器,它和普通函數(shù)不同,生成一個 generator 看起來像函數(shù)調(diào)用,但不會執(zhí)行任何函數(shù)代碼,直到對其調(diào)用next()(在 for 循環(huán)中會自動調(diào)用next())才開始執(zhí)行。雖然執(zhí)行流程仍按函數(shù)的流程執(zhí)行,但每執(zhí)行到一個yield語句就會中斷,并返回一個迭代值,下次執(zhí)行時從yield的下一個語句繼續(xù)執(zhí)行??雌饋砭秃孟褚粋€函數(shù)在正常執(zhí)行的過程中被yield中斷了數(shù)次,每次中斷都會通過yield返回當前的迭代值(yield暫停一個函數(shù),next()從其暫停處恢復(fù)其運行)。

另外對于生成器,python還提供了一個生成器表達式:類似與一個yield值的匿名函數(shù)。表達式本身看起來像列表推到, 但不是用方括號而是用圓括號包圍起來:

>>> unique_characters = {'E', 'D', 'M', 'O', 'N', 'S', 'R', 'Y'}
>>> gen = (ord(c) for c in unique_characters)
>>> gen
<generator object <genexpr> at 0x7f2be4668678>
>>> for i in gen:
...   print(i)
... 
69
79
83
77
82
78
89
68
>>> 

如果需要,可以將生成器表達式傳給tuple、list或是set來迭代所有的值并且返回元組、列表或是集合。在這種情況下,不需要一對額外的括號 ———— 直接將生成器表達式 ord(c) for c in unique_characters傳給tuple()等函數(shù)就可以了, Python 會推斷出它是一個生成器表達式。

最后,為什么要使用生成器?因為效率。使用生成器表達式取代列表解析可以同時節(jié)省 cpu 和 內(nèi)存(ram)。如果你構(gòu)造一個列表的目的僅僅是傳遞給別的函數(shù),(比如 傳遞給tuple()或者set()), 那就用生成器表達式替代吧!

以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。

相關(guān)文章

  • python 中的列表生成式、生成器表達式、模塊導入

    python 中的列表生成式、生成器表達式、模塊導入

    這篇文章主要介紹了python中的列表生成式、生成器表達式、模塊導入 ,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • Python函數(shù)參數(shù)的4種方式

    Python函數(shù)參數(shù)的4種方式

    本文主要介紹了Python函數(shù)參數(shù)的4種方式,主要包括必選參數(shù),默認參數(shù),可選參數(shù),關(guān)鍵字參數(shù),具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Pygame Draw繪圖函數(shù)的具體使用

    Pygame Draw繪圖函數(shù)的具體使用

    Pygame 中提供了一個draw模塊用來繪制一些簡單的圖形狀,比如矩形、多邊形、圓形、直線、弧線等,本文就詳細的介紹一下如何使用
    2021-11-11
  • 基于Python記錄一場2023的煙花

    基于Python記錄一場2023的煙花

    彈指間,2023已經(jīng)到來,新的一年,祝大家新年快樂~~~本文將利用Python為大家繪制一個2023的煙花,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-01-01
  • Python中__init__和__new__的區(qū)別詳解

    Python中__init__和__new__的區(qū)別詳解

    這篇文章主要介紹了Python中__init__和__new__的區(qū)別詳解,并著重說明了__new__的作用及什么情況下使用__new__,需要的朋友可以參考下
    2014-07-07
  • python實現(xiàn)html轉(zhuǎn)ubb代碼(html2ubb)

    python實現(xiàn)html轉(zhuǎn)ubb代碼(html2ubb)

    這篇文章主要介紹了python實現(xiàn)html轉(zhuǎn)ubb代碼(html2ubb),使用正則表達式寫的一個函數(shù),需要的朋友可以參考下
    2014-07-07
  • Python 尋找局部最高點的實現(xiàn)

    Python 尋找局部最高點的實現(xiàn)

    今天小編就為大家分享一篇Python 尋找局部最高點的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • 基于Python實現(xiàn)五子棋-(人機對戰(zhàn))

    基于Python實現(xiàn)五子棋-(人機對戰(zhàn))

    這篇文章主要為大家詳細介紹了如何利用Python實現(xiàn)五子棋游戲(人機對戰(zhàn)版),文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2022-05-05
  • python實現(xiàn)會員管理系統(tǒng)

    python實現(xiàn)會員管理系統(tǒng)

    這篇文章主要為大家詳細介紹了python實現(xiàn)會員管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 淺談Python 多進程默認不能共享全局變量的問題

    淺談Python 多進程默認不能共享全局變量的問題

    今天小編就為大家分享一篇淺談Python 多進程默認不能共享全局變量的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01

最新評論