3. Python3 中的迭代器

  • 迭代器的定義:具有__next__(或者next,python2)方法的對象。
  • 自動可迭代的迭代器:實現(xiàn)__iter__方法的迭代器。通常迭代器是指自動可迭代的迭代器
  • 迭代器的優(yōu)勢:相比使用List迭代,如果迭代數(shù)據(jù)量很大,List方法將消耗大量內(nèi)存,而迭代器可以節(jié)約不少內(nèi)存。獲取速度和內(nèi)存的提升。
  • 其他優(yōu)勢:簡單、通用、優(yōu)雅
  • 迭代器的終止:采用異常機(jī)制,在__next__中無法提供下一個值的時候,拋出 raise StopIteration 即可。
  • 迭代器的使用技巧:a) 直接到元組,鏈表;b)生成一次,只使用一次。當(dāng)然重新初始化也是可行的,不建議用。

失敗的版本

以 Fibs 數(shù)列為例子。

>>> class Fibs():
...     def __init__(self):
...         self.a = 0
...         self.b = 1
...     def __next__(self):
...         self.a, self.b = self.b, self.a+self.b
...         return self.a
... 
>>> fibs = Fibs()
>>> print(fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__())
1 1 2 3 5 8
>>> for f in fibs:
...     print(f)
...     if (f>100):
...         break
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Fibs' object is not iterable

錯誤提示為:Fibs的對象確實是迭代器(能夠手動通過__next__給出迭代結(jié)果),但是不可自動迭代。盡管我們已經(jīng)有了__next__的方法,卻沒有實現(xiàn)__iter__方法。

成功的版本

>>> class Fibs():
...     def __init__(self):
...         self.a = 0
...         self.b = 1
...     def __next__(self):
...         self.a, self.b = self.b, self.a+self.b
...         return self.a
...     def __iter__(self):
...         return self
... 
>>> fibs = Fibs()
>>> print(fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__())
1 1 2 3 5 8
>>> for f in fibs:
...     print(f)
...     if (f>100):
...         break
... 
13 21 34 55 89 144

添加了__iter__函數(shù),該迭代器可以自動迭代了。注意,自動迭代是在手動迭代的基礎(chǔ)上繼續(xù)進(jìn)行的。

  • 迭代器的終止
    上述例子是通過 if語句主動終止的,如果別人使用你的迭代器,不主動終止,那么肯定就爆了(我已經(jīng)重新啟動過電腦一次了)。主動的終止方式是采用異常 raise StopIteration 即可
>>> class Fibs():
...     def __init__(self):
...         self.a = 0
...         self.b = 1
...     def __next__(self):
...         self.a, self.b = self.b, self.a+self.b
...         if self.a > 100: raise StopIteration
...         return self.a
...     def __iter__(self):
...         return self
... 
>>> fibs = Fibs()
>>> for f in fibs:
...     print(f)
... 
1 1 2 3 5 8 13 21 34 55 89

這樣便不需要額外的stop停止語句。

從迭代器到序列

直接使用truple、list函數(shù)轉(zhuǎn)換

>>> class Fibs():
...     def __init__(self):
...         self.a = 0
...         self.b = 1
...     def __next__(self):
...         self.a, self.b = self.b, self.a+self.b
...         if self.a > 100: raise StopIteration
...         return self.a
...     def __iter__(self):
...         return self
... 
>>> fibs = Fibs()
>>> print(tuple(fibs))
(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89)
>>> fibs = Fibs()
>>> print(list(fibs))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

注意: 迭代器用完了之后,需要重置,不然得不到你要的結(jié)果。最佳的使用方式是用一次,建立一次。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 迭代器(Iterable) 簡單來說,迭代器對象(my_list)可以讓以下代碼正常工作: 如果對象實現(xiàn)了__it...
    SOLAREST閱讀 634評論 0 1
  • PYTHON-進(jìn)階-ITERTOOLS模塊小結(jié)轉(zhuǎn)自wklken:http://wklken.me/posts/20...
    C_Y_閱讀 1,170評論 0 2
  • 對于list、string、tuple、dict等這些容器對象,使用for循環(huán)遍歷是很方便的。在后臺for語句對容...
    菜鳥辣媽閱讀 2,490評論 0 1
  • “老板,還有蛋糕嗎?” “沒了?!?“哦,那算了。” “你什么時候要?” “現(xiàn)在。” “?。俊?“現(xiàn)在!” “好,...
    我是大臉喵呀閱讀 1,743評論 2 1
  • 矗立在戈壁 默默無語也風(fēng)流 一段奇景千古蒼涼 鑄就一生絕唱 留下那蓬勃的滄桑 是你 裝扮了這片亙古寂滅的土地 召喚...
    瀚正閱讀 444評論 0 4

友情鏈接更多精彩內(nèi)容