|
最近在使用Python進(jìn)行數(shù)據(jù)處理的過(guò)程中,使用for循環(huán)來(lái)進(jìn)行迭代處理的次數(shù)比較多,于是萌發(fā)了要寫一篇文章來(lái)總結(jié)python中迭代和生成操作,一方面加深對(duì)Python中這塊知識(shí)的理解,另一方面也鍛煉自己寫技術(shù)類博文的能力,這篇文章算是一次嘗試吧。 迭代迭代的概念維基百科中 迭代(Iteration) 的一個(gè)通用概念是:重復(fù)某個(gè)過(guò)程的行為,這個(gè)過(guò)程中的每次重復(fù)稱為一次迭代。具體對(duì)應(yīng)到Python編程中就是,對(duì)于一個(gè)可迭代對(duì)象,比如Python中的list、tuple、string、dictionary,set等,使用某種循環(huán)結(jié)構(gòu)來(lái)遍歷其中的元素,這種遍歷就是迭代。 迭代的形式whilepython編程中可以使用while循環(huán)進(jìn)行迭代。
for在Python編程中,利用for循環(huán)進(jìn)行迭代是比較常見的一種形式。Python使用for...in...的語(yǔ)法結(jié)構(gòu)。這點(diǎn)和C、Java等語(yǔ)言利用下標(biāo)進(jìn)行迭代有點(diǎn)不一樣。下面給出幾個(gè)例子。
除了上面的幾種比較常見的迭代使用形式,for...in...循環(huán)中還有一些tricks。下面總結(jié)的是一些比較常見的,不一定全面。 enumerate當(dāng)我們想在一次迭代中不僅返回迭代對(duì)象中的元素的值,同時(shí)還想返回該元素對(duì)應(yīng)的下標(biāo),那么就可以使用enumerate()函數(shù),該函數(shù)能在一次迭代中同時(shí)返回元素值和對(duì)應(yīng)的下標(biāo)。當(dāng)想建立兩個(gè)迭代對(duì)象元素之間的對(duì)應(yīng)關(guān)系時(shí),enumerate可以作為一種方法。
zipzip是python的一個(gè)內(nèi)建函數(shù),接收一系列可迭代對(duì)象作為參數(shù),將對(duì)象中對(duì)應(yīng)的元素打包成一個(gè)個(gè)tuple(元組),然后返回由這些元組組成的list列表。若傳入的對(duì)象的長(zhǎng)度不等,則返回的list與參數(shù)中長(zhǎng)度最短的對(duì)象相同。
item()item()方法允許我們同時(shí)操作dictionary的key和value, 用起來(lái)也十分方便。
迭代器(iterator)迭代器是訪問(wèn)集合中元素的一種方式,從集合中的第一個(gè)元素開始訪問(wèn),直到所有的元素都被訪問(wèn)一遍后結(jié)束。迭代器不能回退,只能往前進(jìn)行迭代。迭代器的一個(gè)優(yōu)點(diǎn)是不需要事先準(zhǔn)備好集合中的所有元素,僅僅在迭代至某個(gè)元素時(shí)才計(jì)算該元素。適合用于遍歷一些大的文件或集合。同時(shí)迭代器提供了一個(gè)統(tǒng)一的訪問(wèn)集合的接口,只要是定義了iter()方法的對(duì)象,就可以使用迭代器進(jìn)行訪問(wèn)??梢员籲ext()方法調(diào)用并不斷返回下一個(gè)值的對(duì)象稱為迭代器,換句話說(shuō),迭代器對(duì)象具有next()方法。生成器就是迭代器對(duì)象,list、tuple、str等雖然是可迭代對(duì)象(Iterable),但不是迭代器(Iterator)。要把一個(gè)可迭代對(duì)象轉(zhuǎn)換成迭代器,可以使用iter()函數(shù)。另外可以使用isinstance()函數(shù)來(lái)判斷一個(gè)對(duì)象是可迭代對(duì)象還是迭代器對(duì)象。 對(duì)于迭代器的理解,可以把迭代器看成是一個(gè)數(shù)據(jù)流,迭代器對(duì)象被next()函數(shù)調(diào)用不斷返回下一個(gè)數(shù)據(jù),直到?jīng)]有數(shù)據(jù)時(shí)拋出StopIteration錯(cuò)誤。把這個(gè)數(shù)據(jù)流看做是一個(gè)有序序列,但卻不能提前知道這個(gè)數(shù)據(jù)流到底有多長(zhǎng),而對(duì)于list、tuple等可迭代對(duì)象來(lái)說(shuō),對(duì)象的長(zhǎng)度是可知的。這也是可迭代對(duì)象和迭代器的區(qū)別所在。
生成生成的意思是說(shuō)通過(guò)某種規(guī)則產(chǎn)生一定的序列,在生成的過(guò)程中可能也會(huì)用到迭代操作。 列表生成式(list comprehension)列表生成式是一種方便簡(jiǎn)潔的創(chuàng)建List的方式。創(chuàng)建一個(gè)List的一般思路可能是先創(chuàng)建一個(gè)空的List,然后再使用for循環(huán)進(jìn)行迭代,將每次迭代生成的值通過(guò)append方法添加到List中去。
如果使用列表生成式,代碼則會(huì)相當(dāng)簡(jiǎn)潔。
生成器(generator)使用列表生成式的確可以生成一定規(guī)則的列表,但同時(shí)由于內(nèi)存限制,列表容量是有限的。有時(shí)我們可能不想讓一個(gè)列表占用太大的內(nèi)存空間,我們希望在循環(huán)的過(guò)程中值是不斷推算不斷生成的,不必一次性創(chuàng)建完整的序列,從而節(jié)省內(nèi)存空間。Python中就有這種一邊循環(huán)一邊計(jì)算的機(jī)制,這種機(jī)制叫生成器。關(guān)于生成器,還有一種定義說(shuō),帶有yield的函數(shù)就被稱為生成器。帶有yield的函數(shù)不再是一個(gè)普通函數(shù),python解釋器會(huì)把它視為生成器。值得注意的是,生成器是可迭代對(duì)象,也是迭代器對(duì)象。 先講一種簡(jiǎn)單的創(chuàng)建一個(gè)生成器的方法,就是直接把列表生成式的[]換成()就創(chuàng)建了一個(gè)生成器。生成器具有next()方法,用于輸出每次迭代值。
值得注意的是。使用next()方法,當(dāng)?shù)阶詈笠粋€(gè)元素,沒(méi)有更多的元素時(shí),生成器會(huì)拋出StopIteration錯(cuò)誤。下面通過(guò)在函數(shù)中插入yield的方法來(lái)創(chuàng)建生成器。
yield把fab函數(shù)變成了一個(gè)生成器,每次循環(huán)執(zhí)行到語(yǔ)句 yield b 時(shí),fab函數(shù)就返回一個(gè)迭代值,下次迭代時(shí),代碼會(huì)從 yield b 語(yǔ)句的下一條語(yǔ)句繼續(xù)執(zhí)行,就好像是函數(shù)執(zhí)行過(guò)程中被yield中斷了數(shù)次,每次中斷都會(huì)通過(guò)yield返回當(dāng)前的迭代值。這個(gè)過(guò)程可以通過(guò)在代碼中嵌入打印一些標(biāo)記來(lái)進(jìn)行可視化。
小結(jié)可以使用for循環(huán)進(jìn)行迭代的對(duì)象都是可迭代(Iterable)類型,可以調(diào)用next()方法的對(duì)象都是迭代器(Iterator)類型,生成器(generator)既是可迭代類型,也是迭代器類型。 參考 |
|
|