一文帶你探尋Python中的迭代器
面試官: 聽(tīng)說(shuō)你熟悉python
,那么你能簡(jiǎn)單闡述一下python
的裝飾器、生成器以及迭代器么?
我: emm, 我不清楚,我只是了解過(guò)python
最基本的代碼。
上述是弟弟前段時(shí)間去面試運(yùn)維開(kāi)發(fā),遇到的問(wèn)題,emmm,運(yùn)維是一個(gè)很雜的職業(yè),在小公司,總結(jié)一句話就是寬而淺,痛定思痛,決定來(lái)了解一下python
特性,于是乎,就有了這篇文章。
這篇文章,我們將介紹python
迭代器,使用環(huán)境為: Python 3.6.8
什么是迭代器
什么是python
迭代器呢? 舉一個(gè)最簡(jiǎn)單的例子:
list1 = ["pdudo","juejin","hello"] tuple1 = ("pdudo","juejin","hello") dict1 = {"name":"pdudo"} for i in list1: print(i) for i in tuple1: print(i) for i in dict1: print(i)
這就是python
迭代器,好了,講完了,手工。
是的,使用for...in
的方式,底層都是使用的是迭代器,你是不是之前寫(xiě)的時(shí)候,從來(lái)沒(méi)有好奇過(guò),為什么遍歷不同的數(shù)據(jù)類(lèi)型,都可以使用for...in
通用呢?
弟弟我也是一樣的,沒(méi)有想過(guò),為什么可以這樣寫(xiě)。迭代器語(yǔ)法我們已經(jīng)講了,接下來(lái),我們來(lái)剝開(kāi)迭代器的面紗吧。
為什么需要迭代器
只要符合python
迭代器條件的,都可以使用for...in
來(lái)遍歷元素,即: 使用相同的代碼,遍歷不同的數(shù)據(jù)容器。 我認(rèn)為這是根本原因。
如果上述描述還不清晰的話,我們可以使用c
和python
來(lái)遍歷一下數(shù)組 和 字符串,就能清晰的了解了。
如上代碼,是c
語(yǔ)言遍歷數(shù)組"pdudo","hello","juejin"
和字符串pdudohellojuejin
,我們需要自己寫(xiě)遍歷條件的臨界值。
而如何使用python
來(lái)寫(xiě)呢? 來(lái)看下呢。
list1 = ["pdudo","hello","juejin"] char1 = "pdudohellojuejin" for v in list1: print(v) for c in char1: print(c)
只需要定義數(shù)組和字符串,而后使用for...in
便結(jié)束了。
我想,如上例子,就足以證明為什么要使用迭代器的原因了,因?yàn)檎娴暮芩?/p>
迭代器是如何工作的
在經(jīng)歷了前2個(gè)段落的鋪墊,我猜你肯定很想知道迭代器是如何工作的吧?現(xiàn)在它來(lái)了。
在使用for...in
語(yǔ)句時(shí),它會(huì)調(diào)用inter()
對(duì)象,該函數(shù)會(huì)返回一個(gè)迭代器對(duì)象。該對(duì)象又定義了__next__()
方法,該方法一次返回一個(gè)容器元素,當(dāng)沒(méi)有更多元素可以返回的時(shí)候,會(huì)拋一個(gè)StopIteration
異常來(lái)表明for
終止循環(huán)。
是不是還是不懂?沒(méi)關(guān)系,我們?cè)賹?xiě)一個(gè)案例來(lái)說(shuō)明一下。
list1 = ["pdudo","hello","juejin"] it = iter(list1) print(next(it)) print(next(it)) print(next(it)) print(next(it))
如上代碼,定義了一個(gè)列表,其值為: "pdudo","hello","juejin",而后調(diào)用iter
方法,它將返回一個(gè)迭代器,而后調(diào)用next
方法來(lái)返回下一個(gè)元素,但是我們定義的列表長(zhǎng)度為3,而調(diào)用了4次next
方法,可見(jiàn),最后一次會(huì)拋異常。
我們執(zhí)行后,效果如下:
可見(jiàn),和我們上述猜想的一致,在for...in
語(yǔ)句中,也是調(diào)用inter()
容器對(duì)象,使用__next__
返回后續(xù)可迭代的對(duì)象,如此類(lèi)推,直至遇到異常StopIteration
,循環(huán)結(jié)束。
好了,知道迭代器是如何工作了吧? 那么,我們?cè)賿伋鲆粋€(gè)問(wèn)題,看你能否接住呢? 如何判斷一個(gè)數(shù)據(jù)類(lèi)型是能夠被迭代的呢?
如何創(chuàng)建一個(gè)迭代器
我們已經(jīng)學(xué)會(huì)了如何使用迭代器,以及知曉了迭代器是如何工作的,本段落將介紹如何創(chuàng)建一個(gè)迭代器,在看這個(gè)之前,我們思考一個(gè)問(wèn)題,如下代碼是否會(huì)報(bào)錯(cuò)呢?
a = 9527 for i in a: print(i)
我們使用for...in
來(lái)遍歷一個(gè)int
類(lèi)型的數(shù)據(jù)。
如上代碼,當(dāng)然會(huì)報(bào)錯(cuò),借此引出我們的知識(shí)點(diǎn):什么樣的數(shù)據(jù)類(lèi)型才能被迭代呢?
是這樣的,能否被迭代,取決于該方法是否有__iter__
方法。
可以看下如下例子,我們自定義了一個(gè)迭代器,用于倒敘輸出數(shù)據(jù)。
#!/bin/env python class flashBack: def __init__(self,list1): self.data = list1 self.index = len(list1)-1 def __iter__(self): return self def __next__(self): if self.index < 0: raise StopIteration val = self.data[self.index] self.index = self.index - 1 return val def main(): list1 = [1,2,3,4,5] tuble1 = ("pdudo","juejin","hello") for i in flashBack(list1): print(i) for i in flashBack(tuble1): print(i) if __name__ == '__main__': main()
執(zhí)行后,結(jié)果為:
可見(jiàn),創(chuàng)建一個(gè)迭代器,至少需要 __iter__
方法 和 有__next__
方法。
好了,有了這個(gè)基礎(chǔ)案例,我們來(lái)寫(xiě)一個(gè)鏈表?
#!/bin/env python class Node: def __init__(self,val): self.val = val self.nextNode = None class Lists: def __init__(self,currentNodes): self.currentNode = currentNodes def __iter__(self): return self def __next__(self): if self.currentNode is None: raise StopIteration v = self.currentNode.val self.currentNode = self.currentNode.nextNode return v def main() : node1 = Node(1) node2 = Node(2) node3 = Node(3) node1.nextNode = node2 node2.nextNode = node3 for i in Lists(node1): print(i) if __name__ == '__main__': main()
如上代碼,我們先創(chuàng)建節(jié)點(diǎn)Node
,它有2個(gè)值,val
是記錄的值,而nextNode
是記錄下一個(gè)Node
的指針,而后定義了類(lèi)Lists
,調(diào)用時(shí)候,需要傳入一個(gè)Node
,它會(huì)將currentNodes
來(lái)記錄當(dāng)前的Node
重點(diǎn)看__next__
,當(dāng)當(dāng)前節(jié)點(diǎn)為空的時(shí)候,則返回StopIteration
告知for
迭代器結(jié)束了,否則的話,取出當(dāng)前節(jié)點(diǎn)的val
并且返回,且將其下滑到下一個(gè)節(jié)點(diǎn)。
如上代碼,運(yùn)行后,結(jié)果如下:
總結(jié)
本篇文章,我們首先介紹了什么迭代器,什么是迭代器呢? 最簡(jiǎn)單的for...in
就是迭代器,接著便介紹了為什么需要迭代器,我們通過(guò)c
輸出數(shù)組和字符串來(lái)和python
的for...in
語(yǔ)法做比較,迭代器寫(xiě)法更為簡(jiǎn)單,迭代器的核心是使用相同的代碼,遍歷不同的數(shù)據(jù)容器。 接著便介紹了迭代器是如何工作的,其對(duì)象方法必須要有__iter__
和__next__
方法,才能被for...in
所調(diào)用,最后我們實(shí)現(xiàn)了一個(gè)類(lèi),實(shí)現(xiàn)了上述的2個(gè)方法,從而實(shí)現(xiàn)了迭代器。
以上就是一文帶你探尋Python中的迭代器的詳細(xì)內(nèi)容,更多關(guān)于Python迭代器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python連接kafka加載數(shù)據(jù)的項(xiàng)目實(shí)踐
本文主要介紹了python連接kafka加載數(shù)據(jù)的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05python導(dǎo)出requirements.txt的幾種方法以及環(huán)境配置詳細(xì)流程
這篇文章主要給大家介紹了關(guān)于python導(dǎo)出requirements.txt的幾種方法以及環(huán)境配置詳細(xì)流程,requirements.txt 文件是一個(gè)文本文件,用于列出你的Python項(xiàng)目所依賴(lài)的軟件包及其版本,需要的朋友可以參考下2023-11-11Tensorflow矩陣運(yùn)算實(shí)例(矩陣相乘,點(diǎn)乘,行/列累加)
今天小編就為大家分享一篇Tensorflow矩陣運(yùn)算實(shí)例(矩陣相乘,點(diǎn)乘,行/列累加),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02淺談TensorFlow中讀取圖像數(shù)據(jù)的三種方式
這篇文章主要介紹了淺談TensorFlow中讀取圖像數(shù)據(jù)的三種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Python實(shí)現(xiàn)自定義順序、排列寫(xiě)入數(shù)據(jù)到Excel的方法
這篇文章主要介紹了Python實(shí)現(xiàn)自定義順序、排列寫(xiě)入數(shù)據(jù)到Excel的方法,涉及Python針對(duì)Excel文件的數(shù)據(jù)處理及讀寫(xiě)相關(guān)操作技巧,需要的朋友可以參考下2018-04-04Python自動(dòng)化xpath實(shí)現(xiàn)自動(dòng)搶票搶貨
這篇文章主要介紹了Python自動(dòng)化xpath實(shí)現(xiàn)自動(dòng)搶票搶貨,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09python 讀寫(xiě)中文json的實(shí)例詳解
這篇文章主要介紹了 python 讀寫(xiě)中文json的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家掌握這樣的內(nèi)容,需要的朋友可以參考下2017-10-10