- 迭代器的定義:具有__next__(或者next,python2)方法的對象裸删。
- 自動可迭代的迭代器:實現(xiàn)__iter__方法的迭代器八拱。通常迭代器是指自動可迭代的迭代器
- 迭代器的優(yōu)勢:相比使用List迭代,如果迭代數(shù)據(jù)量很大涯塔,List方法將消耗大量內(nèi)存肌稻,而迭代器可以節(jié)約不少內(nèi)存。獲取速度和內(nèi)存的提升匕荸。
- 其他優(yōu)勢:簡單爹谭、通用、優(yōu)雅
- 迭代器的終止:采用異常機制榛搔,在__next__中無法提供下一個值的時候诺凡,拋出 raise StopIteration 即可。
- 迭代器的使用技巧:a) 直接到元組践惑,鏈表绑洛;b)生成一次,只使用一次童本。當然重新初始化也是可行的真屯,不建議用。
失敗的版本
以 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ù)進行的烈掠。
- 迭代器的終止
上述例子是通過 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é)果叼风。最佳的使用方式是用一次,建立一次棍苹。