python基础(part15)--迭代
鄙人學(xué)習(xí)筆記
開(kāi)發(fā)工具:Spyder
文章目錄
- 迭代
- 舉個(gè)例子1
- 舉個(gè)例子2
- for循環(huán)原理
- 可迭代對(duì)象iterable
- 舉個(gè)例子1
- 舉個(gè)例子2
- 舉個(gè)例子3
- 迭代器對(duì)象iterator
- yield關(guān)鍵字迭代原理
- 舉個(gè)例子(我們將之前的MyRange類進(jìn)行改寫)
迭代
每一次對(duì)過(guò)程的重復(fù)為一次”迭代”,而每一次迭代得到的結(jié)果,會(huì)作為下一次迭代的初始值。例如:循環(huán)獲取容器中的元素。
舉個(gè)例子1
創(chuàng)建一個(gè)列表:
再輸入以下代碼:
結(jié)果:
可以看出,我們得到的結(jié)果和for循環(huán)遍歷這個(gè)列表,得到的結(jié)果相同。
如果我們多寫一個(gè)iterator.__next__(),會(huì)怎樣呢?
結(jié)果:
會(huì)報(bào)錯(cuò) python警告我們,要 Stop Iteration, 停止迭代!
舉個(gè)例子2
還是創(chuàng)建原來(lái)的列表:
我們?cè)倮靡韵路椒ǖ?#xff1a;
第39行代碼這樣寫,其實(shí)相當(dāng)于在except之后寫了個(gè)異常基類:
結(jié)果:
我們發(fā)現(xiàn),我們沒(méi)有用for循環(huán),也拿到了可迭代對(duì)象(列表)內(nèi)元素。以上兩個(gè)例子演示了for循環(huán)原理。
for循環(huán)原理
現(xiàn)在,我們對(duì)上面例子中的代碼進(jìn)行解釋,進(jìn)而闡述一下for循環(huán)原理
①獲取迭代器對(duì)象
我們說(shuō),可迭代對(duì)象,是具有__iter__()方法,可以返回迭代器的對(duì)象。所以以后我們?cè)u(píng)判一個(gè)對(duì)象是不是可迭代對(duì)象時(shí),就可以看一看,這個(gè)對(duì)象有沒(méi)有__iter__()方法,如果有這個(gè)方法,則說(shuō)明,這個(gè)對(duì)象是可以被迭代的。
②獲取下一個(gè)元素(迭代)
有迭代器之后,我們就可以迭代了,__next__()的過(guò)程就是在迭代的過(guò)程,有__next__()我們就可以拿到下一個(gè)元素。
③停止迭代(StopIteration錯(cuò)誤)
最后,我們總結(jié)一下for循環(huán)原理:
①獲取迭代器對(duì)象
②循環(huán)迭代(調(diào)用迭代器的__next__()方法)
③捕獲StopIteration異常
- 小問(wèn)題
問(wèn):能夠被for循環(huán)的條件是什么?
答:具有__iter__()方法的對(duì)象。
- 例子1
使用while + 迭代器,獲取元祖(“小白”, “小黃”, “大白”)中所有元素。
代碼:
t01 = ("小白", "小黃", "大白") iterator = t01.__iter__()while True:try:item = iterator.__next__()print(item)except:break結(jié)果:
- 例子2
不使用for循環(huán),獲取字典{“小白”:0, “小黃”:6, “大白”:7}中的key和value.
代碼:
d01 = {"小白":0, "小黃":6, "大白":7}iterator = d01.__iter__()while True:try:key = iterator.__next__()print(key, d01[key])except:break結(jié)果:
備注:使用迭代器迭代字典,拿到的是字典的key
可迭代對(duì)象iterable
- 定義
具有__iter__()函數(shù)的對(duì)象,可以返回迭代器對(duì)象.
- 語(yǔ)法
創(chuàng)建可迭代對(duì)象:
class 可迭代對(duì)象名稱:def __iter__(self):return 迭代器使用可迭代對(duì)象:
for 變量名 in 可迭代對(duì)象:語(yǔ)句- 原理
舉個(gè)例子1
首先創(chuàng)建兩個(gè)類:
再創(chuàng)建SkillManager對(duì)象,并試著迭代此對(duì)象的成員變量skills:
得到結(jié)果:
結(jié)果得到了列表內(nèi)的各個(gè)Skill對(duì)象。
但是,如果我們只迭代SkillManager對(duì)象會(huì)怎樣呢?我們看看下面這個(gè)例子。
舉個(gè)例子2
利用例子1,創(chuàng)建的兩個(gè)類:
再創(chuàng)建SkillManager對(duì)象,并試著迭代此對(duì)象:
運(yùn)行:
報(bào)錯(cuò)!且python提示我們SkillManager對(duì)象是個(gè)不可迭代的對(duì)象。
接下來(lái),我們就要讓SkillManager可迭代!
我們先要在SkillManager類里增加一個(gè)__iter__()方法,使他變?yōu)榭傻鷮?duì)象。 這個(gè)__iter__()被調(diào)用后,應(yīng)該返回一個(gè)迭代器類對(duì)象SkillIterator。這個(gè)迭代器類對(duì)象里應(yīng)該有一個(gè)__next__()方法,用于返回下一個(gè)元素。在__next__()方法里應(yīng)該拋出一個(gè)索引越界異常,當(dāng)被迭代對(duì)象全部迭代完后,再獲取下一個(gè)元素,則會(huì)拋出異常。具體情況,我們看看下面的代碼。
現(xiàn)在我們看一下SkillManager類:
再看一下SkillIterator類:
創(chuàng)建對(duì)象,并開(kāi)始利用for循環(huán)原理,進(jìn)行迭代:
我們?cè)龠\(yùn)行一下,看一下運(yùn)行結(jié)果:
不錯(cuò)!可迭代對(duì)象內(nèi)元素全部拿到了。
備注1:由上面的過(guò)程我們也可以看出,可迭代對(duì)象不會(huì)直接return它的元素,而是由迭代器return了可迭代對(duì)象內(nèi)的元素。
備注2:若我們用for循環(huán),則它也會(huì)先獲取迭代器對(duì)象,獲取完迭代器對(duì)象后,再用迭代器對(duì)象不斷的調(diào)用__next__()方法,直到迭代器對(duì)象拋出異常,for再進(jìn)行異常處理。
舉個(gè)例子3
參照下例代碼,定義MyRange類,實(shí)現(xiàn)相同效果:
代碼:
結(jié)果:
備注:誰(shuí)要被for,誰(shuí)要就有__iter__()方法,這個(gè)方法可以獲取迭代器,迭代器內(nèi)部具體怎么寫?看需求!迭代器中有__next__(),可以返回下一個(gè)元素。
迭代器對(duì)象iterator
- 定義
可以調(diào)用__next__()函數(shù),并返回下一個(gè)值得對(duì)象。
- 語(yǔ)法
- 說(shuō)明
聚合對(duì)象通常是容器對(duì)象。
- 作用
使用者只通過(guò)一種方式(for循環(huán)),便可以簡(jiǎn)潔明了獲取聚合對(duì)象中的各個(gè)元素,而又無(wú)需了解可迭代對(duì)象的內(nèi)部存儲(chǔ)結(jié)構(gòu)。
==備注!==若我們?cè)赺_iter__()方法內(nèi)不返回自己創(chuàng)建的迭代器對(duì)象,而用yield關(guān)鍵字自動(dòng)生成迭代器對(duì)象,會(huì)怎樣呢?
請(qǐng)看以下案例
代碼:
結(jié)果:
執(zhí)行過(guò)程:
①客戶端調(diào)用__iter__()方法,__iter__()方法不執(zhí)行, 進(jìn)入while循環(huán).
②客戶端調(diào)用__next__()方法,__iter__()方法執(zhí)行,先執(zhí)行print("準(zhǔn)備返回第一個(gè)元素"), 執(zhí)行到y(tǒng)ield語(yǔ)句, 將yield后的數(shù)據(jù)作為_(kāi)_next__()方法的返回值return給item, 并且暫時(shí)離開(kāi)__iter__()方法, 繼續(xù)執(zhí)行while循環(huán)中的print(item).
③當(dāng)再次調(diào)用__next__()方法時(shí),從上次離開(kāi)的代碼開(kāi)始執(zhí)行,再運(yùn)行到下一個(gè)yield語(yǔ)句,return數(shù)據(jù)之后,并再次暫時(shí)離開(kāi).
④待執(zhí)行完__iter__()方法體,若再次調(diào)用__next__()方法,會(huì)自動(dòng)拋出StopIteration異常.
yield關(guān)鍵字迭代原理
- 原理
如果方法體中包含yield關(guān)鍵字,那么會(huì)自動(dòng)生成迭代器對(duì)象.
生成迭代器代碼的大致規(guī)則:
①將yield關(guān)鍵字前的代碼,放到__next__()方法中.
②將yield關(guān)鍵字后的數(shù)據(jù),作為_(kāi)_next__()方法的返回值.
舉個(gè)例子(我們將之前的MyRange類進(jìn)行改寫)
代碼:
結(jié)果:
若我們不定義類,而只定義包含yield的方法,來(lái)滿足我們迭代的需求,該怎么做呢?
代碼:
結(jié)果:
我們說(shuō)這項(xiàng)技術(shù),就叫做生成器generator函數(shù).
總結(jié)
以上是生活随笔為你收集整理的python基础(part15)--迭代的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 赵州桥的主要特点
- 下一篇: python基础(part16)--生成