>>s='abc'>>>it=ite" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python的迭代器和生成器

系統 1694 0

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

            
>>> s = 'abc'
>>> it = iter(s)
>>> it

            
              
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
 File "
              
                ", line 1, in 
                
                  
StopIteration

                
              
            
          

上面說的都是python自帶的容器對象,它們都實現了相應的迭代器方法,那如果是自定義類需要遍歷怎么辦?方法很簡單,對這個類AClass,實現一個__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數,max是生成的fibonacci序列中數字大小的上限。

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

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

下面說生成器。

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

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

          

關于迭代器和生成器的區別,生成器能做到迭代器能做的所有事,而且因為自動創建了__iter__()和 next()方法,生成器顯得特別簡潔,而且生成器也是高效的。除了創建和保存程序狀態的自動方法,當發生器終結時,還會自動拋出StopIteration異常。一個帶有yield的函數就是一個 生成器,它和普通函數不同,生成一個 generator 看起來像函數調用,但不會執行任何函數代碼,直到對其調用next()(在 for 循環中會自動調用next())才開始執行。雖然執行流程仍按函數的流程執行,但每執行到一個yield語句就會中斷,并返回一個迭代值,下次執行時從yield的下一個語句繼續執行。看起來就好像一個函數在正常執行的過程中被yield中斷了數次,每次中斷都會通過yield返回當前的迭代值(yield暫停一個函數,next()從其暫停處恢復其運行)。

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

            
>>> unique_characters = {'E', 'D', 'M', 'O', 'N', 'S', 'R', 'Y'}
>>> gen = (ord(c) for c in unique_characters)
>>> gen

            
              
                 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()等函數就可以了, Python 會推斷出它是一個生成器表達式。

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

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


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美中文在线观看 | 亚洲国产一区二区三区最新 | 久久久久爽亚洲精品 | 成年女人18级毛片毛片 | 奇米影视第七色 | 午夜影视在线观看 | 天天骑夜夜操 | 亚洲视频观看 | 老司机永久免费网站在线观看 | 九九热精品视频 | 国产日韩一区二区三区在线观看 | 亚洲免费视 | 日韩欧美亚洲国产精品字幕久久久 | 国产精品v | 欧美成人精品高清在线播放 | 色大18成网站www在线观看 | 久久久国产这里有的是精品 | 久久精品国产午夜伦班片 | 久久精品日日躁夜夜躁欧美 | 欧美日韩综合在线视频免费看 | 精品久久久久久久久久香蕉 | 久久大综合 | 四虎永久免费在线观看 | 综合亚洲欧美 | 欧美精品日韩一区二区三区 | 久久国产精品高清一区二区三区 | 奇米影视第四色在线观看 | 久cao在线观看视频 久re这里只有精品最新地址 | 国产只有精品 | se成人国产精品 | 国产二区视频 | 午夜精品久久久久久99热 | 亚洲视频在线观看不卡 | 天天操视频 夜夜 | 中文字幕日韩精品中文区 | 2020国产成人精品视频人 | 国产精品一区二区久久沈樵 | 香蕉久久一区二区三区 | 欧美精品日本一级特黄 | 国产成人丝袜网站在线观看 | 91精品中文字幕 |