99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网

歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

Python學(xué)習(xí)之迭代器詳解 

發(fā)布時間:2017-02-19 22:23  回復(fù):0  查看:2130   最后回復(fù):2017-02-19 22:23  

設(shè)計 api 的時候,可以利用 python 的 描述符 完成很多工作,而這些描述符操作,還有一個名字就是“ 魔法方法 ”,現(xiàn)在我們一起來認識一下迭代器神功,希望對大家學(xué)習(xí)python有所幫助

迭代器( iterator )是訪問集合內(nèi)元素的一種方式,提供了一種遍歷類序列對象的方法。對于一般的序列,利用索引從0一直迭代到序列的最后一個元素。對象從集合的第一個元素開始訪問,直到所有的元素都被訪問一遍后結(jié)束。對于字典、文件、自定義對象類型等,可以自定義迭代方式,從而實現(xiàn)對這些對象的遍歷??傊?,迭起器就是定義了對對象進行遍歷的方式。

一些編程語言C,C++需要實現(xiàn)這樣的結(jié)構(gòu)。另外一些高級語言python,ruby則把迭代協(xié)議在語言層面就實現(xiàn)了。當(dāng)然,這樣的隱藏了一些細節(jié),有時候明明已經(jīng)使用了,卻渾然不知。

iter 函數(shù)

python提供了一個 iter 函數(shù)用來生成迭代器。這個方法有兩個參數(shù),當(dāng)只有一個參數(shù)的時候,若這個參數(shù)是一個 容器 ,則返回這個容器的 迭代器對象 ,若這個參數(shù)本身就是一個 迭代器 ,則返回其自身。

In [1]: alist = [1, 2, 3, 4]

In [2]: it = iter(alist)

In [3]: itOut[3]:

In [4]: it2 = iter(it)

In [5]: id(it) == id(it2)Out[5]: True

iterator 的特點

迭代器都有一個 next 方法,每次調(diào)用這個方法而實現(xiàn)計數(shù),當(dāng)然計數(shù)不是通過索引實現(xiàn),調(diào)用了next方法只會,迭代指針會指向下一個元素的位置。若下一個元素沒有了,則會拋出 StopIteration 異常。

In [6]: it.next()Out[6]: 2

In [7]: it.next()Out[7]: 3

In [8]: it.next()Out[8]: 4

In [9]: it.next()---------------------------------------------------------------------------StopIteration Traceback(mostrecentcalllast)

<ipython-input-16-54f0920595b2in <module>()----> 1 it.next()

StopIteration:

In [10]:

這樣做有什么用呢?試想想在迭代指針還沒指到的當(dāng)前元素時候,已經(jīng)迭代之后的位置元素,那些元素需要計算么?因為只有迭代到當(dāng)前位置的元素時候,才開始計算元素的值。在迭代之前可以不存在,在迭代之后可以被銷毀。實現(xiàn)的迭代器不需要準(zhǔn)備所遍歷的所有元素,沒錯,這就是迭代器的一大魅力,惰性計算。

for 循環(huán)

知道了迭代器大致的用法,我們來遍歷一個迭代器。

In [1]: it = iter(range(4))

In [2]: try:

...while True:

...: printit.next()

...: exceptStopIteration:

...: pass

...:0123

In [3]:

上面的遍歷看上去比較別扭,更不沒有python優(yōu)雅的感覺,或許,想到遍歷一個容器,for in循環(huán)更優(yōu)雅

In [3]: it = range(4)

In [4]: for i in it:

...: print i

...:0123

In [5]:

兩次運算的效果幾乎一樣,那么for循環(huán)的機理是什么呢。前面所言python內(nèi)置實現(xiàn)了各種迭代協(xié)議,for循環(huán)就是一個很好的例子。for 循環(huán)的時候,首先對循環(huán)對象實現(xiàn)迭代器包裝,返回一個迭代器對象,然后每循環(huán)一步,就調(diào)用哪個迭代器對象的next方法,循環(huán)結(jié)束的時候,自動處理了 StopIteration這個異常。for循環(huán)是對迭代器進行迭代的語法糖。無處不在的語法糖。

當(dāng)然實現(xiàn)迭代器的時候,有時候會把索引丟掉,在python可以使用內(nèi)建函數(shù) enumerate 獲取索引。

iterator 的定義

對于上面的 it 這個迭代器,是通過 iter方法實現(xiàn)的,那么iter函數(shù)到底做了什么呢?簡而言之,實現(xiàn)了迭代器協(xié)議的對象,就是迭代器。什么事迭代器協(xié)議呢?再簡而言之,滿足下面兩個條件即可:

· 實現(xiàn)了魔法方法 __iter__() ,返回一個迭代對象,這個對象有一個 next() 方法,

· 實現(xiàn) next() 方法,返回當(dāng)前的元素,并指向下一個元素的位置,當(dāng)前位置已經(jīng)沒有元素的時候,拋出StopIteration 異常。

前面我們迭代range(4)是從零開始,現(xiàn)在我們實現(xiàn)一個迭代器對象,可以逆序迭代的。

class ReverseList():

def__init__(self, item):

self.list = range(item)

def__iter__(self):

return self

defnext(self):

try:

return self.list.pop()

except:

raiseStopIteration

In [1]: it = ReverseList(4)

In [2]: it.next()

Out[2]: 3

In [3]: it.next()

Out[3]: 2

In [4]: it.next()

Out[4]: 1

In [5]: it.next()

Out[5]: 0

In [6]:

更復(fù)雜的遍歷邏輯,都可以在 next 方法里構(gòu)造。當(dāng)然,看到了這里,也就大概知道了迭代器的協(xié)議,也已經(jīng)是python的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)了的。并且還沒見識到惰性計算。其實吧,惰性計算,python有更好的處理魔法,就是生成器,關(guān)于生成器,比迭代器神功還有效。

接下來就是用迭代器的迭代之后銷毀元素的特性,做一個練習(xí)吧。

有一個偶數(shù)項的列表 a = ["foo", 2, "bar", 4, "far", 6] ,希望對每兩個相鄰的兩個元素打包,是為一組,使得結(jié)果如下是這樣的 [("foo", 2), ("bar", 4), ("far", 6)] 。如果是要打包是每三個一組呢?

有很多方法可以解決,下面使用迭代器進行處理,大概代碼如下:

a = ["foo", 2, "bar", 4, "far", 6]

group_adjacent = lambda x, k: zip(*([iter(x)] * k))

In [1]: a = ["foo", 2, "bar", 4, "far", 6]

In [2]: group_adjacent = lambda x, k: zip(*([iter(x)] * k))

In [3]: group_adjacent(a, 2)

Out[3]: [(\\'foo\\', 2), (\\'bar\\', 4), (\\'far\\', 6)]

In [4]:

對于迭代器,python還有很多高級功能,并且還專門有一個 itertools 標(biāo)準(zhǔn)庫用來做迭代器對象的相關(guān)處理。

迭代器魔法沒有裝飾器那么驚艷,卻有著魔幻的力量,配合生成器,更有另一番天地。


來源:伯樂在線

您還未登錄,請先登錄

熱門帖子

最新帖子

?