迭代器是能夠迭代的對象。 在本教程中,您將瞭解迭代器的工做原理,以及如何使用__iter__
和__next__
方法構建本身的迭代器。html
迭代器在Python中無處不在。 它們優雅地實如今循環,推導,生成器等中,但隱藏在明顯的視覺中。python
Python中的迭代器只是一個能夠迭代的對象。一個將一次返回數據的對象或一個元素。shell
從技術上講,Python迭代器對象必須實現兩個特殊的方法__iter__()
和__next__()
,統稱爲迭代器協議。yii
若是咱們從中獲取一個迭代器,那麼一個對象被稱爲iterable
。 大多數Python中的內置容器是列表,元組,字符串等都是可迭代的。函數
iter()
函數(這又調用__iter__()
方法)返回一個迭代器。oop
使用next()
函數來手動遍歷迭代器的全部項目。當到達結束,沒有更多的數據要返回時,它將會引起StopIteration
。 如下是一個例子。ui
# define a list my_list = [4, 7, 0, 3] # get an iterator using iter() my_iter = iter(my_list) ## iterate through it using next() #prints 4 print(next(my_iter)) #prints 7 print(next(my_iter)) ## next(obj) is same as obj.__next__() #prints 0 print(my_iter.__next__()) #prints 3 print(my_iter.__next__()) ## This will raise error, no items left next(my_iter)
更優雅的自動迭代方式是使用for
循環。 使用for
循環能夠迭代任何能夠返回迭代器的對象,例如列表,字符串,文件等。spa
>>> for element in my_list: ... print(element) ... 4 7 0 3
在上面的例子中看到的,for
循環可以自動經過列表迭代。code
事實上,for
循環能夠迭代任何可迭代對象。咱們來仔細看一下在Python中是如何實現for
循環的。htm
for element in iterable: # do something with element
實際上它是以相似下面的方式來實現的 -
# create an iterator object from that iterable iter_obj = iter(iterable) # infinite loop while True: try: # get the next item element = next(iter_obj) # do something with element except StopIteration: # if StopIteration is raised, break from loop break
因此在for
的內部,for
循環經過在可迭代的對象上調用iter()
來建立一個迭代器對象iter_obj
。
有意思的是,這個for
循環其實是一個無限循環~..~。
在循環中,它調用next()
來獲取下一個元素,並使用該值執行for
循環的主體。 在全部對象耗盡後,引起StopIteration
異常,內部被捕獲從而結束循環。請注意,任何其餘類型的異常都將正常經過。
構建迭代器在Python中很容易。只須要實現__iter__()
和__next__()
方法。
__iter__()
方法返回迭代器對象自己。若是須要,能夠執行一些初始化。
__next__()
方法必須返回序列中的下一個項目(數據對象)。 在到達結束後,並在隨後的調用中它必須引起StopIteration
異常。
在這裏,咱們展現一個例子,在每次迭代中給出下一個2
的幾回方。 次冪指數從零開始到用戶設定的數字。
class PowTwo: """Class to implement an iterator of powers of two""" def __init__(self, max = 0): self.max = max def __iter__(self): self.n = 0 return self def __next__(self): if self.n <= self.max: result = 2 ** self.n self.n += 1 return result else: raise StopIteration
如今能夠建立一個迭代器,並經過它迭代以下 -
>>> a = PowTwo(4) >>> i = iter(a) >>> next(i) 1 >>> next(i) 2 >>> next(i) 4 >>> next(i) 8 >>> next(i) 16 >>> next(i) Traceback (most recent call last): ... StopIteration
也可使用for
循環迭代那些迭代器類。
>>> for i in PowTwo(5): ... print(i) ... 1 2 4 8 16 32
迭代器對象中的項目沒必要都是可耗盡的,能夠是無限迭代器(永遠不會結束)。 處理這樣的迭代器時必定要當心。
下面是用來演示無限迭代器的一個簡單的例子。
內置的函數iter()
能夠用兩個參數來調用,其中第一個參數必須是可調用對象(函數),而第二個參數是標頭。迭代器調用此函數,直到返回的值等於指定值。
>>> int() 0 >>> inf = iter(int,1) >>> next(inf) 0 >>> next(inf) 0
能夠看到,int()函
數老是返回0
,因此將它做爲iter(int,1)
傳遞將返回一個調用int()
的迭代器,直到返回值等於1
。這歷來沒有發生,因此這樣就獲得一個無限迭代器。
咱們也能夠創建本身的無限迭代器。 如下迭代器理論上將返回全部奇數。
class InfIter: """Infinite iterator to return all odd numbers""" def __iter__(self): self.num = 1 return self def __next__(self): num = self.num self.num += 2 return num
示例運行以下 -
>>> a = iter(InfIter()) >>> next(a) 1 >>> next(a) 3 >>> next(a) 5 >>> next(a) 7
當迭代這些類型的無限迭代器時,請注意指定終止條件。
使用迭代器的優勢是它們能夠節省資源。 如上所示,咱們能夠得到全部奇數,而不將整個系統存儲在內存中。理論上,能夠在有限的內存中計算有無限的項目。
原文出自【易百教程】,商業轉載請聯繫做者得到受權,非商業轉載請保留原文連接:https://www.yiibai.com/python/iterator.html