python可迭代對象,生成器和迭代器你搞懂了麼

本文主要給大家分享python中可迭代對象,生成器與迭代它們到底是什麼?有什麼用,彼此之間的區別與聯繫。

一、可迭代對象

python中提供的內建類型比如列表、元組、字典和字符串等集合類型都支持迭代操作,迭代是訪問集合中元素的一種方式,迭代簡單點就是遍歷集合中的每個元素。對於列表,元組,字符串,set數據類型來說可以直接作用於for循環的對象統稱為可迭代對象(Iterable)。

字符串迭代如下圖示,通過迭代我們可以訪問字符串中的每一個元素。

python可迭代對象,生成器和迭代器你搞懂了麼

我們使用for循環時,只要作用於一個可迭代對象,for循環就可以正常運行,而不用太關心該對象究竟是list還是其他數據類型。

二、如何判斷一個對象是不是一個可迭代對象

我們可以通過python自帶的一個collections模塊中的Iterable類型判斷。如下例所示:

python可迭代對象,生成器和迭代器你搞懂了麼

三、生成器是什麼

除了序列數據類型比如列表,元組和字符串可以作用於for循環外,還有生成器也可以作用於for循環。

我們用列表生成式可以快速創建一個列表,如果列表中的元素有100萬,會耗費大量的內存空間。有沒有一種方法在我們需要某個元素的時候在生成,這樣就比較節省空間。就像我們去餐館吃飯一樣,現吃現做,如果都提前做好了就會佔用很大的空間來放置。其實生成器就是這樣一種東西,在你遍歷到某個元素時它才會生成某個元素,它其實保存的是一種生成元素的算法。在Python中,這種一邊循環一邊計算的機制我們稱為生成器(generator)。

創建生成器主要有兩種方式:

第一種:將一個列表生成式的[]改成()

python可迭代對象,生成器和迭代器你搞懂了麼

通過上圖我們發現生成器保存的是算法,如果要生成或計算下一個元素我們可以使用python中的內建函數next()獲取。如下例所示:

python可迭代對象,生成器和迭代器你搞懂了麼


元素多的話使用next一個一個獲取顯然不現實,一般會通過使用for循環來實現,因為生成器本身就是一個可迭代對象。示例如下:

python可迭代對象,生成器和迭代器你搞懂了麼

第二種:創建生成器的方法在函數中使用yield關鍵字

當我們生成元素的算法如果比較複雜的時候,藉助類似列表生成式這樣的方式很難實現。這個時候我們可以藉助函數來實現。

比如我們獲取一個斐波那契數列的集合。

python可迭代對象,生成器和迭代器你搞懂了麼

當一個函數中使用了yield關鍵字後,這個函數就不再是一個普通函數,而是變成一個生成器。該函數返回的是一個生成器對象。yield和return這兩個關鍵字都是用來返回某個值,但是他們的主要區別是在函數中如果執行到return語句就會結束整個函數,而yield在返回某個值後,會在停留的位置繼續向下執行,直到把整個函數體語句執行完才結束。

四.迭代器

生成器都是迭代器對象,但是列表,元組,字符串等類型雖然是可迭代對象,但它們不是迭代器,因為Python的Iterator對象表示的是一個數據流,Iterator對象可以被next()函數調用並不斷返回下一個數據,直到沒有數據時拋出StopIteration錯誤。可以把這個數據流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數實現按需計算下一個數據,所以Iterator的計算是惰性的,只有在需要返回下一個數據時它才會計算。

把list、dict、str,tuple等可迭代對象(Iterable)變成Iterator可以使用iter()函數實現轉換。

對列表直接調用next獲取值就會報錯,因為只有迭代器對象可以被next函數調用。

python可迭代對象,生成器和迭代器你搞懂了麼

通過使用iter()函數可以將可迭代對象轉為迭代器。

python可迭代對象,生成器和迭代器你搞懂了麼

因此我們在執行for循環進行迭代某一個可迭代對象時,其實是等價於下圖中第二個紅框中的代碼:

python可迭代對象,生成器和迭代器你搞懂了麼

任何實現了__iter__和__next__()方法的對象都是迭代器,演示代碼如下:

python可迭代對象,生成器和迭代器你搞懂了麼

其中__iter__方法返回迭代器自身,而__next__方法返回迭代器中的下一個

python可迭代對象,生成器和迭代器你搞懂了麼

小結:

凡是可以作用於for循環的對象都是可迭代對象。

凡是作用於next函數的對象都是迭代器。

生成器即是一個可迭代對象,又是一種特殊的迭代器,因為迭代器一般要求實現__iter__和__next__方法。

對於python中的集合類型比如列表,元組,字符串和字典它們都是可迭代對象,但是它們不是迭代器,可以通過iter函數轉換為迭代器。其實可迭代對象是一個大概念;它包含生成器,序列類型(元組,字典,字符串)和迭代器。

如果你認為本文對你有價值的話,請給勇哥點個贊,你的認可是我堅持下來的最大動力。我的python專欄和爬蟲專欄已經開設,有需要的話可以進行購買學習。


分享到:


相關文章: