一篇文章弄懂Python中的可迭代對象、迭代器和生成器
我們都知道,序列可以迭代。但是,你知道為什么嗎? 本文來探討一下迭代背后的原理。
序列可以迭代的原因:iter 函數(shù)。解釋器需要迭代對象 x 時(shí),會(huì)自動(dòng)調(diào)用 iter(x)。內(nèi)置的 iter 函數(shù)有以下作用:
(1) 檢查對象是否實(shí)現(xiàn)了 iter 方法,如果實(shí)現(xiàn)了就調(diào)用它,獲取一個(gè)迭代器。
(2) 如果沒有實(shí)現(xiàn) iter 方法,但是實(shí)現(xiàn)了 getitem 方法,而且其參數(shù)是從零開始的索引,Python 會(huì)創(chuàng)建一個(gè)迭代器,嘗試按順序(從索引 0 開始)獲取元素。
(3) 如果前面兩步都失敗,Python 拋出 TypeError 異常,通常會(huì)提示“C objectis not iterable”(C 對象不可迭代),其中 C 是目標(biāo)對象所屬的類。
由此我們可以明確知道什么是 可迭代的對象: 使用 iter 內(nèi)置函數(shù)可以獲取迭代器的對象。即要么對象實(shí)現(xiàn)了能返回迭代器的 iter 方法,要么對象實(shí)現(xiàn)了 getitem 方法,而且其參數(shù)是從零開始的索引。
下面看一個(gè)實(shí)現(xiàn)了getitem方法的例子:
輸出結(jié)果:
我們創(chuàng)建了一個(gè)類Eg1,并且為這個(gè)類實(shí)現(xiàn)了 getitem 方法, 它的實(shí)例化對象o1 就是可迭代對象。
下面我們看一個(gè)實(shí)現(xiàn) iter 方法的例子,因?yàn)橛玫搅说鳎栽诖宋覀儽仨氃诿鞔_一下迭代器的用法。 標(biāo)準(zhǔn)的迭代器接口有兩個(gè)方法:
返回下一個(gè)可用的元素,如果沒有元素了,拋出 StopIteration異常。
返回 self,以便在應(yīng)該使用可迭代對象的地方使用迭代器,例如在 for 循環(huán)中。
我們創(chuàng)建了Eg2類,并為它實(shí)現(xiàn)了 iter 方法,此方法返回一個(gè)迭代器Eg2Iterator。 Eg2Iterator 實(shí)現(xiàn)了我們之前所說的next和iter方法。 實(shí)例化對象,并循環(huán)輸出:
可見,和o1是一樣的。
我們通過兩種方法實(shí)現(xiàn)了一個(gè)自己的可迭代對象,再此過程中我們要明確可迭代的對象和迭代器之間的關(guān)系:
Python 從可迭代的對象中獲取迭代器。
iter方法從我們自己創(chuàng)建的迭代器類中獲取迭代器,而getitem方法是python內(nèi)部自動(dòng)創(chuàng)建迭代器。
至此,我們明白了如何正確地實(shí)現(xiàn)可迭代對象,并且引出了怎樣實(shí)現(xiàn)迭代器,但是使用迭代器方法(即上面的例子2)的代碼量有點(diǎn)大,下面我們來了解一下如何使用更符合 Python 習(xí)慣的方式實(shí)現(xiàn) Eg2類。
哦了!就這么簡單優(yōu)雅!不用再單獨(dú)定義一個(gè)迭代器類!
這里我們使用了yield 關(guān)鍵字, 只要 Python 函數(shù)的定義體中有 yield 關(guān)鍵字,該函數(shù)就是生成器函數(shù)。調(diào)用生成器函數(shù)時(shí),會(huì)返回一個(gè)生成器對象。也就是說,生成器函數(shù)是生成器工廠。 當(dāng)然,例子3的代碼還可以使用yield from進(jìn)一步簡化:
到這里我們明白了 可迭代對象 和 迭代器,還引申出了生成器,但還有一點(diǎn)沒有提,那就是生成器表達(dá)式。
使用生成器表達(dá)式例子4的代碼可以修改為:
在python中,所有生成器都是迭代器。
最后,總結(jié)一下:
(1)什么是可迭代對象? 可迭代對象要么實(shí)現(xiàn)了能返回迭代器的 iter 方法,要么實(shí)現(xiàn)了 getitem 方法而且其參數(shù)是從零開始的索引。
(2)什么是迭代器? 迭代器是這樣的對象:實(shí)現(xiàn)了無參數(shù)的 next 方法,返回下一個(gè)元素,如果沒有元素了,那么拋出 StopIteration 異常;并且實(shí)現(xiàn)iter 方法,返回迭代器本身。
(3)什么是生成器? 生成器是帶有 yield 關(guān)鍵字的函數(shù)。調(diào)用生成器函數(shù)時(shí),會(huì)返回一個(gè)生成器對象。
(4)什么是生成器表達(dá)式? 生成器表達(dá)式是創(chuàng)建生成器的簡潔句法,這樣無需先定義函數(shù)再調(diào)用。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。
相關(guān)文章
Django使用httpresponse返回用戶頭像實(shí)例代碼
這篇文章主要介紹了Django使用httpresponse返回用戶頭像實(shí)例代碼2018-01-01pandas DataFrame實(shí)現(xiàn)幾列數(shù)據(jù)合并成為新的一列方法
今天小編就為大家分享一篇pandas DataFrame實(shí)現(xiàn)幾列數(shù)據(jù)合并成為新的一列方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06Python實(shí)現(xiàn)實(shí)時(shí)增量數(shù)據(jù)加載工具的解決方案
這篇文章主要分享結(jié)合單例模式實(shí)際應(yīng)用案例:實(shí)現(xiàn)實(shí)時(shí)增量數(shù)據(jù)加載工具的解決方案。最關(guān)鍵的是實(shí)現(xiàn)一個(gè)可進(jìn)行添加、修改、刪除等操作的增量ID記錄表。需要的可以參考一下2022-02-02python通過BF算法實(shí)現(xiàn)關(guān)鍵詞匹配的方法
這篇文章主要介紹了python通過BF算法實(shí)現(xiàn)關(guān)鍵詞匹配的方法,實(shí)例分析了BF算法的原理與Python實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03使用Keras實(shí)現(xiàn)Tensor的相乘和相加代碼
這篇文章主要介紹了使用Keras實(shí)現(xiàn)Tensor的相乘和相加代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06