深刻理解python的迭代器,生成器,可迭代對象區別

要先搞清楚這三者區別首先須要給文章點個贊。呸呸呸,說錯了,須要先弄明白什麼是迭代,先補充一下迭代的概念在進入正題的講解。python

迭代:像list,tuple,dict這樣的數據類型,咱們經過for...in...語法從中依次拿到數據進行使用,這樣的遍歷過程,就叫作迭代程序員


正文開始

1,可迭代對象

簡單來講,某個對象內部具備__iter__方法,那麼它就是可迭代對象(Iterable)。面試

全劇終!事情並非這麼簡單,做爲一個有追求的程序員咱們須要深刻了解一下可迭代對象的本質是什麼?函數

咱們分析咱們在對可迭代對象進行迭代的時候,迭代一次(就是在for...in...中循環一次),都會返回一個值,直到將可迭代對象中的全部值取完。cdn

那麼問題來了,是否是存在一個「人」記錄了何時訪問到了第幾個數據。答案是確定的,這個「人」就是迭代器(Iterator)對象

可迭代對象的本質就是提供這樣個迭代器幫助咱們進行迭代遍歷使用blog

可迭代對象就是經過__iter__方法向咱們提供這樣一個迭代器,在迭代一個可迭代對象的時候,首先就是獲取該對象的迭代器,而後利用該迭代器對可迭代對象中的數值進行迭代。it

綜上所述,一個具有了__iter__方法的對象,就是一個可迭代對象。io


接下來進入迭代器的講解,咱們再補充一點概念性的東西class

iter()函數與next()函數

list、tuple等都是可迭代對象,咱們能夠經過iter()函數獲取這些可迭代對象的迭代器。

而後咱們能夠對獲取到的迭代器不斷使用next()函數來獲取下一條數據。

iter()函數實際上就是調用了可迭代對象的__iter__方法。

當序列遍歷完時,將拋出一個StopIteration異常。這將使迭代器與循環兼容,由於它們將捕獲這個異常以中止循環。 要建立定製的迭代器,能夠編寫一個具備next方法的類。


2,迭代器

經過上面的分析,相信你已經掌握了迭代器就是幫我記錄每次迭代訪問的位置,當咱們對迭代器使用next()函數的時候,迭代器會向咱們返回它所記錄位置的下一個位置的數據。

實際上咱們使用的next函數,調用的就是迭代器對象的__next__方法(python3中是__next__方法,python2中是next()方法)

因此咱們想要構造一個迭代器就是要實現他的__next__方法,可是實現__next__方法還遠遠不夠,python要求迭代器自身也是能夠進行迭代的,因此咱們還要爲迭代器實現__iter__方法,而__iter__方法要返回一個迭代器,迭代器自身正是一個迭代器,因此迭代器的__iter__方法返回自身便可。

是否是像一個繞口令,十分難記,簡答來講

迭代器就是一個實現了__iter__和__next__方法的對象


經過以上講解,你須要明白的一些結論

若是一個對象擁有__iter__方法,那麼它是可迭代對象;

若是一個對象擁有next方法,其是迭代器;

定義可迭代對象,必須實現__iter__方法;

定義迭代器,必須實現__iter__和next方法;

迭代器必定是可迭代對象,反過來則不必定成立。用iter()函數能夠把list、dict、str等Iterable變成Iterator


3,生成器

進入到今天的最後一個話題。激動!(一不當心又掌握了一個面試必考點,圈起來)

生成器是一種特殊的迭代器,生成器自動實現了「迭代器協議」(即__iter__和next方法),不須要再手動實現兩方法。

生成器在迭代的過程當中能夠改變當前迭代值,而修改普通迭代器的當前迭代值每每會發生異常,影響程序的執行。

具備yield關鍵字的函數都是生成器,yield能夠理解爲return,返回後面的值給調用者。

不一樣的是return返回後,函數會釋放,而生成器則不會。

在直接調用next方法或用for語句進行下一次迭代時,生成器會從yield下一句開始執行,直至遇到下一個yield

固然是點贊啊,哈哈哈哈

相關文章
相關標籤/搜索