文章摘錄至:iteratorpython
何謂Iterator?
實際上, 他就是一個迭代器. 在每種編程語言裏面, 都有 for...of.. 或者 for...in... 等相似簡便遍歷。 這裏遍歷運用的機理就是迭代器.
在python裏面, 基本上全部的數據結構都有迭代器的屬性. 好比: list,tuple,set,string等. 迭代器對象上有兩個基本方法:編程
__iter__(): 返回iterator 對象數據結構
__next__(): 返回下一個值的內容編程語言
上面這兩種,就叫作iterator protocol. 就和在js中的[Symbol.iterator]方法同樣, 他須要具有next=>{vlaue,done} 這樣的返回內容.函數
每個iterator 都會具有兩個基本的method. 就是上面所述的 __iter__(),__next__(). 另外, 你還能夠顯示的使用 iter()和next()來進行調用, 其實內部也是調用__iter__(),__next__() 兩個方法.
以list爲例:ui
a_list = [x for x in range(10)] print(a_list.__iter__()) # 獲得的就是iterator對象 <list_iterator object at 0x102e431d0>
固然,也可使用iter()方法進行轉化.
咱們接下來就能夠利用__next__()進行迭代.spa
iter_of_list = a_list.__iter__() print(iter_of_list.__next__()) # 0 print(iter_of_list.__next__()) # 1 print(iter_of_list.__next__()) # 2
當已經遍歷到最後時, __next__() 則會返回StopIteration 的異常. 因此,這須要進行捕獲排除.
好比, 咱們可使用while模擬一下,簡單的for...in... 遍歷code
iter_of_list = a_list.__iter__() def iterable(iterable): while True: try: print(iterable.__next__()) except StopIteration: break iterable(iter_of_list)
Iterator就是爲for...in...這種快捷遍歷方式而準備的. 若是有時候,咱們自定義了本身的數據結構, 而且也想使用for...in...循環那應該怎麼作呢? 方法是有的, 只要你本身定義了__iter__(),__next__()這 兩個方法便可.對象
通過上面的介紹, 咱們大體瞭解到. 使用__iter__() 是用來返回iterator對象. 那麼應該怎麼返回呢? 實際上,只要返回你自身便可. 即至關於,返回一個對象, 他能夠調用__iter__(),__next__()這 兩個方法.
而 __next__() 則使用來返回下一個值(固然, 怎麼返回時看你本身定義的)
看個詳細的demo:rem
class Xlist: def __init__(self,a_list): self.list = a_list self.index = 0 def __iter__(self): return self def __next__(self): length = len(self.list) if(length==self.index): # 提出異常 raise StopIteration else: result = self.list[self.index] self.index += 1 return result a_list = [x for x in range(10)] x_list = Xlist(a_list) for x in x_list: print(x)
這裏,還有個trick. 咱們能夠構建一個無限迭代的Iterator. 有兩種方法: 1. 直接使用iter()函數 2. 本身構建Iterator. 無限迭代經常使用於數字類型, 咱們也已理解爲,隨着時間推移,獲取增加型數字的過程. 在python中, 無限迭代並不會讓你的程序崩潰,只要你不利用已經產生的全部值來do something, 更泛一點的說法是, 不引用之前所產生的所有結果.
使用iter()函數
他的基本格式除了: iter(iterable)
這樣調用, 還有一種是:
iter(callable, sentinel)
callable是用來產生值的 函數, sentinel是上限值.
咱們來生成無限個1:
infinit_1 = iter(lambda :1,2) # 訪問 infinite_1 = iter(lambda :1,2) for x in infinite_1: print(x)
但這種方式,比較boring, 不夠靈活, 咱們可使用自定義的iterator來完成. 他的關鍵點就在於, 只要咱們不提出 StopIteration 則, 迭代器就會一直持續下去
使用自定義Iterator
接下來,咱們能夠用這個來模擬生成無限個偶數的效果.
# 運行需謹慎 class InfiniteOdd: def __init__(self,start=1): self.start = start def __iter__(self): return self def __next__(self): result = self.start self.start *=2 return result odd = InfiniteOdd() for x in odd: print(x)
最後看一下總結吧: