轉自:http://www.cnblogs.com/zhbzz2007/p/6102695.htmlhtml
1 迭代器:python
迭代器,容許你在一個容器上進行迭代的對象。函數
python的迭代器主要是經過__iter__和__next__兩個方法來實現。spa
__iter__,要求你的容器支持迭代,返回對象自己。若是想建立一個迭代器對象,還須要實現__next__方法,這個返回下一個對象。code
爲了對這些概念更加清晰,讓咱們回顧下面的兩個定義:htm
全部函數名中有雙下劃線的方法,都很神奇,你不須要直接調用__iter__或者__next__。你可使用for循環或者轉換爲列表,Python就會自動替你調用這些方法。固然你或許仍是想調用它們,那麼你可使用Python內置的函數iter和next方法。對象
python3中,list是支持迭代的,但不是迭代器對象。由於,它不支持__next__blog
看代碼:generator
a=[1,2,3,4,5]
next(a)
錯誤信息是:it
C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py Traceback (most recent call last): File "C:/Users/wcf/PycharmProjects/Algorithms/wcf.py", line 3, in <module> next(a) TypeError: 'list' object is not an iterator Process finished with exit code 1
經過iter內建函數,能夠把他轉變成迭代器:
a=[1,2,3,4,5] for item in iter(a): print(item)
當你使用循環來遍歷一個迭代器,你就不須要調用next方法,你也無需擔憂會收到StopIteration異常信息。
好比:
a=[1,2,3,4,5] a_iter=iter(a) next(a_iter) next(a_iter) next(a_iter) next(a_iter) next(a_iter) next(a_iter) next(a_iter)
會出錯的:
C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py Traceback (most recent call last): File "C:/Users/wcf/PycharmProjects/Algorithms/wcf.py", line 10, in <module> next(a_iter) StopIteration Process finished with exit code 1
2.建立屬於本身的迭代器,很簡單,實現幾個方法就能夠:
class my_iterator(): def __init__(self,letters): self.letters=letters self.position=0 def __iter__(self): return self def __next__(self): if self.position>=len(self.letters): raise StopIteration letter=self.letters[self.position] self.position+=1 return letter if __name__=="__main__": i=my_iterator('abcd') for item in i: print(item)
3.生成器
一個普通的Python函數常常返回一個值,不管它是列表、整數仍是其餘對象。可是若是你想調用一個函數,這個函數可否產生一系列值呢?這個就是生成器誕生的緣由。生成器的工做機制是保存它所中止(或者說它已經產生)的位置,而後給主調函數返回一個值。不是返回一個調用函數的執行,生成器僅僅返回一個臨時的控制返回。爲了完成這個功能,生成器函數須要使用Python的 yield 語句。
def double_generator(): number=2 while True: yield number number+=2 doubler =double_generator() print(next(doubler)) print(next(doubler)) print(next(doubler)) print(next(doubler))
輸出是:
C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py 2 4 6 8 Process finished with exit code 0
實際上,上文,也有一個next方法。
而下面的例子,就是沒有:
def double_generator(): yield 'wcf1' yield 'wcf2' yield 'wcf3' doubler =double_generator() print(next(doubler)) print(next(doubler)) print(next(doubler))
輸出是:
C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py
wcf1
wcf2
wcf3
Process finished with exit code 0
一樣的,若是是:
def double_generator(): yield 'wcf1' yield 'wcf2' yield 'wcf3' doubler =double_generator() print(next(doubler)) print(next(doubler)) print(next(doubler)) print(next(doubler))
同樣會觸發一場:
C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py wcf1 Traceback (most recent call last): wcf2 wcf3 File "C:/Users/wcf/PycharmProjects/Algorithms/wcf.py", line 12, in <module> print(next(doubler)) StopIteration Process finished with exit code 1
而這樣寫,就ok:
def double_generator(): yield 'wcf1' yield 'wcf2' yield 'wcf3' doubler =double_generator() for item in doubler: print(item)