Python生成器generator原理及用法解析
前言
生成器generator
生成器的本質(zhì)是一個迭代器(iterator)
要理解生成器,就要在理解一下迭代,可迭代對象,迭代器,這三個概念
Python生成器generator簡介
iteration, iterable, iterator
迭代(iteration):在python中迭代通常是通過for...in...來實現(xiàn)的.而且只要是可迭代對象iterable,都能進行迭代.
可迭代對象(iterable):Python中的任意的對象,只要它定義了可以返回一個迭代器的 __iter__方法,或者定義了可以支持下標(biāo)索引的__getitem __方法,那么它就是一個可迭代對象。簡單說,可迭代對象就是能提供迭代器的任意對象.返回的是一個iterator 對象.官方解釋
迭代器(iterator ) : 簡單的說,迭代器就是實現(xiàn)了iterator.__iter__() 和iterator.__next__() 的對象,iterator.__iter__()方法返回的是iterator對象本身.根據(jù)官方的說法,正是這個方法,實現(xiàn)了for ... in ...語句.而iterator.__next__()是iterator區(qū)別于iterable的關(guān)鍵了,它允許我們顯式地獲取一個元素.當(dāng)調(diào)用next()方法時,實際上產(chǎn)生了2個操作:
更新iterator狀態(tài),令其指向后一項,以便下一次調(diào)用,每一個值過后,指針移動到下一位,對iterator遍歷完后,其變成了一個空的容器,但不是None ,需要注意的是,迭代結(jié)束后,指針不會自動返回到首位,而是依舊停留在末位置,想要在開始,需要重新載入迭代對象.
實例理解:
>>> from collections import Iterable, Iterator >>> a = [1,2,3] # 眾所周知,list是一個iterable >>> b = iter(a) # 通過iter()方法,得到iterator,iter()實際上調(diào)用了__iter__(), >>> isinstance(a, Iterable) True >>> isinstance(a, Iterator) False >>> isinstance(b, Iterable) True >>> isinstance(b, Iterator) True
可見,itertor 一定是iterable ,但iterable不一定是itertor
>>> dir(a) ['__add__','__class__','__contains__','__delattr__','__delitem__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__getitem__','__gt__','__hash__','__iadd__','__imul__','__init__','__iter__','__le__','__len__','__lt__','__mul__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__', '__reversed__','__rmul__', '__setattr__','__setitem__','__sizeof__','__str__', '__subclasshook__','append','clear' 'copy','count','extend','index','insert', 'pop','remove', 'reverse','sort'] >>>dir(b) ['__class__','__delattr__', '__dir__', '__doc__','__eq__', '__format__','__ge__' ,'__getattribute__', '__gt__','__hash__','__init__','__iter__','__le__','__length_hint__', '__lt__','__ne__','__new__','__next__','__reduce__','__reduce_ex__','__repr__','__setattr__', '__setstate__','__sizeof__','__str__','__subclasshook__']
可以看到迭代器具有__next__ 這個方法,可迭代對象具有__getitem__
迭代器是消耗型的,隨著指針的移動,遍歷完畢以后,就為空,但是不是None
>>> c = list(b) >>> c [1, 2, 3] >>> d = list(b) >>> d [] # 空的iterator并不等于None. >>> if b: ... print(1) ... 1 >>> if b == None: ... print(1) ...
使用迭代器的內(nèi)置方法 __next__ 和 next() 方法,遍歷元素
In [73]: e = iter(a) In [74]: next(e) Out[74]: 1 In [75]: e.__next__ Out[75]: <method-wrapper '__next__' of list_iterator object at 0x7f05571c8518> In [76]: e.__next__() Out[76]: 2 In [77]: e.__next__() Out[77]: 3 In [78]: e.__next__() --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-78-6024b5bd9bd2> in <module>() ----> 1 e.__next__() StopIteration:
當(dāng)遍歷完畢時,會返回一個StopIteration 的錯誤.
for...in.... 遍歷迭代
當(dāng)我們對一個iterable 使用for ....in... 進行遍歷時,實際上是想調(diào)用iter() 方法得到一個iterator ,假設(shè)為x ,然后循環(huán)的調(diào)用x 的__next__() (next())方法,取得每一次的值,直到iterator為空,返回StopIteration 作為循環(huán)的結(jié)束的標(biāo)準(zhǔn).for....in...會自動處理 StopIteration 異常,從而避免了拋出異常,從而使程序中斷.流程圖為:
x = [1, 2, 3]
for i in x:
print(x)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于python對B站收藏夾按照視頻發(fā)布時間進行排序的問題
這篇文章主要介紹了基于python對B站收藏夾按照視頻發(fā)布時間進行排序,在實現(xiàn)過程中中間程序可能因為各種原因掛掉,因此在中間加入了儲存中間狀態(tài)的功能,否則每次掛掉都要重新爬速度非常慢,本文給大家介紹具體使用方法,一起看看吧2021-05-05Python中創(chuàng)建相關(guān)系數(shù)矩陣的方法小結(jié)
相關(guān)系數(shù)矩陣是一種用于衡量變量之間關(guān)系的重要工具,本文將介紹在 Python 中創(chuàng)建相關(guān)系數(shù)矩陣的不同方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12如何實現(xiàn)Python調(diào)用Golang代碼詳解
這篇文章主要介紹了如何實現(xiàn)Python調(diào)用Golang代碼,Python和Golang都是當(dāng)下非常流行的編程語言,在實際開發(fā)中,我們可能會遇到需要將Python和Golang進行組合使用的場景,感興趣想要詳細了解可以參考下文2023-05-05python機器學(xué)習(xí)之神經(jīng)網(wǎng)絡(luò)實現(xiàn)
這篇文章主要為大家詳細介紹了python機器學(xué)習(xí)之神經(jīng)網(wǎng)絡(luò)的實現(xiàn)方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-10-10python練習(xí)之循環(huán)控制語句 break 與 continue
這篇文章主要介紹了python循環(huán)控制語句 break 與 continue,break就像是終止按鍵,不管執(zhí)行到哪一步,只要遇到break,不管什么后續(xù)步驟,直接跳出當(dāng)前循環(huán)2022-06-06pycharm設(shè)置默認的UTF-8編碼模式的方法詳解
這篇文章主要介紹了pycharm設(shè)置默認的UTF-8編碼模式,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06利用Python實現(xiàn)斐波那契數(shù)列的方法實例
這篇文章主要給大家介紹了關(guān)于如何利用Python實現(xiàn)斐波那契數(shù)列的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07