Python函數(shù)進(jìn)階之迭代器的原理與使用詳解
什么是迭代器
能被 next 指針調(diào)用,并不斷返回下一個(gè)值的對(duì)象,叫做迭代器。表示為Iterator,迭代器是一個(gè)對(duì)象類型數(shù)據(jù)。
概念
迭代器指的是迭代取值的工具,迭代是一個(gè)重復(fù)的過(guò)程,每次重復(fù)都是基于上一次的結(jié)果而繼續(xù)的,單純的重復(fù)并不是迭代。
特征
迭代器并不依賴索引,而通過(guò) next 指針迭代所有數(shù)據(jù),一次只取一個(gè)值,大大節(jié)省空間。
惰性序列
惰性序列是指沒(méi)有一次性的把所有數(shù)據(jù)都放在序列中,而是遍歷一個(gè)放一個(gè)這樣的序列,range對(duì)象和迭代器能夠產(chǎn)生惰性序列。
檢查可迭代對(duì)象
for循環(huán)的用于遍歷可迭代對(duì)象,簡(jiǎn)單粗暴的來(lái)說(shuō),可以被for循環(huán)遍歷的元素都是可迭代對(duì)象。for 循環(huán)能夠遍歷一切可迭代性數(shù)據(jù)的原因在于,底層調(diào)用了迭代器,通過(guò)next方法中的指針實(shí)現(xiàn)數(shù)據(jù)的獲取。所以普通的非迭代器可迭代對(duì)象和迭代器之間的區(qū)別就是,一個(gè)不能直接使用next調(diào)用,一個(gè)可以被next指針調(diào)用。
再次重復(fù)一遍,可迭代對(duì)象不一定是迭代器,迭代器一定是一個(gè)可迭代對(duì)象。
使用dir()函數(shù)可以查看一個(gè)數(shù)據(jù)中的所有的對(duì)象成員,如果包含有__iter__方法,說(shuō)明就是一個(gè)可迭代對(duì)象。換句話說(shuō),__iter__方法的作用就是返回一個(gè)可迭代對(duì)象。
# 定義一個(gè)列表,列表是可迭代對(duì)象 lst = [1, 2, 3, 4, 5] # 獲取列表的所有成員 res_lst = dir(lst) print(res_lst) ''' ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__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'] ''' # 查看是否存在__iter__方法 res = '__iter__' in res_lst print(res) # True # 存在__iter__方法,說(shuō)明確實(shí)是一個(gè)可迭代對(duì)象
定義迭代器
迭代器的表示方式是iterator。
使用iter函數(shù)
使用 iter 函數(shù)將一個(gè)普通的可迭代對(duì)象轉(zhuǎn)成迭代器。
lst = [1, 2, 3] print(type(lst)) # <class 'list'> it = iter(lst) print(type(it)) # <class 'list_iterator'>
使用__iter__方法
使用 __iter__ 內(nèi)置方法實(shí)現(xiàn)可迭代對(duì)象轉(zhuǎn)成迭代器。
lst = [1, 2, 3] print(type(lst)) # <class 'list'> it = lst.__iter__() print(type(it)) # <class 'list_iterator'>
判斷迭代器
檢查內(nèi)置方法
存在__iter__方法說(shuō)明是可迭代對(duì)象。存在 __next__ 方法說(shuō)明是迭代器,因?yàn)榈骺梢允褂?code>next指針獲取元素。
迭代器中,__iter__和__next__都存在。
產(chǎn)卡是可迭代對(duì)象。
# 列表
lst = list()
# 迭代器
lst_it = iter(lst)
# 迭代器中的所有成員
res_lst = dir(lst_it)
# 判斷
if '__iter__' in res_lst:
print('lst_it是一個(gè)可迭代對(duì)象')
if '__next__' in res_lst:
print('lst_it是一個(gè)迭代器')
'''
結(jié)果:
lst_it是一個(gè)可迭代對(duì)象
lst_it是一個(gè)迭代器
'''
使用collections模塊
導(dǎo)入collections模塊中的Iterator和Iterable類型可以判斷是否是可迭代對(duì)象或者是迭代器。Iterator是迭代器類型數(shù)據(jù)。Iterable是可迭代對(duì)象類型數(shù)據(jù)。利用導(dǎo)入的數(shù)據(jù)類型配合isinstance函數(shù)就可以判斷數(shù)據(jù)的類型。
lst = list() lst_it = iter(lst) # 判斷是否是迭代器 res = isinstance(lst_it, Iterator) print(res) # True # 判斷是否是可迭代對(duì)象 res = isinstance(lst_it, Iterable) print(res) # True
調(diào)用迭代器
調(diào)用迭代器的幾種方法
- 使用
next函數(shù)或者是__next__內(nèi)置方法一個(gè)一個(gè)、一遍一遍的獲取其中的數(shù)據(jù); - 使用for循環(huán)遍歷出來(lái);
- 使用while循環(huán)配合
next函數(shù)或者是__next__內(nèi)置方法; - 強(qiáng)轉(zhuǎn)成為其它的數(shù)據(jù)類型;
使用next方法和函數(shù)
調(diào)用迭代器使用next函數(shù)才可以取出其中的內(nèi)容,next 在調(diào)用迭代器中的數(shù)據(jù)時(shí)單向不可逆的,是一條路走到黑的過(guò)程,如果調(diào)用超出迭代器中的元素個(gè)數(shù),會(huì)報(bào)錯(cuò)StopIteration ,意為停止迭代。
# 因?yàn)閘st本沒(méi)有數(shù)據(jù),所以無(wú)法取出數(shù)據(jù) lst = list() lst_it = iter(lst) res = next(lst_it) # StopIteration print(res)
取出迭代器中的數(shù)據(jù),如果數(shù)據(jù)全部取出要重置迭代器才能再次取出。
lst = [1, 2, 3] lst_it = iter(lst) # 迭代器中一次只會(huì)取出一個(gè)數(shù)據(jù) print(next(lst_it)) # 1 print(next(lst_it)) # 2 print(next(lst_it)) # 3 # 超出迭代器中的元素個(gè)數(shù),就會(huì)報(bào)錯(cuò) print(next(lst_it)) # StopIteration # 如果要重新取出數(shù)據(jù),就重置迭代器,重新定義一邊迭代器就是重置迭代器 lst_it = iter(lst) # 再次取出數(shù)據(jù),使用__next__方法 print(lst_it.__iter__()) # 1 print(lst_it.__iter__()) # 2 print(lst_it.__iter__()) # 3
總結(jié)
使用next函數(shù)調(diào)用
使用for循環(huán)遍歷
強(qiáng)轉(zhuǎn)成為其它的數(shù)據(jù)類型(實(shí)測(cè)容器都可以轉(zhuǎn)成迭代器,但是迭代器只有轉(zhuǎn)成列表才會(huì)有內(nèi)容)
next函數(shù)配合循環(huán)遍歷
到此這篇關(guān)于Python函數(shù)進(jìn)階之迭代器的原理與使用詳解的文章就介紹到這了,更多相關(guān)Python迭代器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python時(shí)間獲取及轉(zhuǎn)換知識(shí)匯總
這篇文章主要介紹了Python時(shí)間獲取及轉(zhuǎn)換知識(shí)匯總的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01
python3+PyQt5實(shí)現(xiàn)文檔打印功能
這篇文章主要為大家詳細(xì)介紹了python3+PyQt5實(shí)現(xiàn)文檔打印功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
Python 解決中文寫入Excel時(shí)拋異常的問(wèn)題
下面小編就為大家分享一篇Python 解決中文寫入Excel時(shí)拋異常的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
conda安裝tensorflow和conda常用命令小結(jié)
這篇文章主要介紹了conda安裝tensorflow和conda常用命令小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
Python利用多線程優(yōu)化for循環(huán)的技巧分享
多線程可以讓程序同時(shí)執(zhí)行多個(gè)任務(wù),從而提高整體運(yùn)行效率,這篇文章將詳細(xì)介紹如何在Python中使用多線程來(lái)優(yōu)化for循環(huán),感興趣的可以了解下2025-02-02
Python提示[Errno 32]Broken pipe導(dǎo)致線程crash錯(cuò)誤解決方法
這篇文章主要介紹了Python提示[Errno 32]Broken pipe導(dǎo)致線程crash錯(cuò)誤解決方法,是ThreadingHTTPServer實(shí)現(xiàn)http服務(wù)中經(jīng)常會(huì)遇到的問(wèn)題,需要的朋友可以參考下2014-11-11
Python利用reportlab實(shí)現(xiàn)制作pdf報(bào)告
這篇文章主要為大家詳細(xì)介紹了reportlab生成流文件格式、reportlab分頁(yè)和圖片流文件寫入reportlab等內(nèi)容,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-12-12
Python對(duì)口紅進(jìn)行數(shù)據(jù)分析來(lái)選定情人節(jié)禮物
情人節(jié)送小仙女什么禮物?讓我們來(lái)用Python對(duì)口紅進(jìn)行數(shù)據(jù)分析,那個(gè)女孩子會(huì)拒絕這樣精心挑選的禮物,感興趣的小伙伴快來(lái)看看吧2022-02-02

