對於乙個列表,a = [1, 2, 3, 4],我們最常見的遍歷方式就是:
a = [1, 2, 3, 4]for item in
a:
print item
這裡我們研究一種新的方式,就是迭代器。
在c++的stl中大量使用了迭代器,迭代器的作用當然就是遍歷容器中的元素,而且他的好處就在於分離了容器的實現和遍歷操作,不管我們使用什麼型別的容器,使用迭代器的操作幾乎是如出一轍。
看下面的**:
>>> a = [2, 3, 4]>>> it =iter(a)
it.next()
2>>> print
it.next()
3>>> print
it.next()
4>>> print
it.next()
traceback (most recent call last):
file
"", line 1, in
stopiteration
>>>
在上面的**中,iter函式建立了乙個可以迭代的物件,然後每次呼叫next方法,都能從其中取出元素。當沒有元素可以迭代時,便丟擲乙個異常stopiteration。
所以我們上面的for迴圈可以這樣改寫:
a = [1, 2, 3, 4]it =iter(a)
item =none
while
true:
try:
item =it.next()
except
stopiteration:
break
print item #
do_something
如何建立迭代器
現在我們想對我們自定義的class進行迭代操作,應該怎麼辦?
這裡的關鍵是實現__iter__和next兩個函式。
#!/usr/bin/env python
#coding: utf-8
class
iterlist:
def__init__
(self, elem):
self.iter =iter(elem)
def__iter__
(self):
return
self
defnext(self):
return
self.iter.next()
if__name__ == '
__main__':
a = [1, 2, 3, 4]
test =iterlist(a)
for item in
test:
print item
這裡我們僅僅是對class內部持有的元素做了乙個包裝,我們的__iter__返回的是自身,next則是呼叫的儲存的iter的next方法。
現在我們提供乙個稍微複雜的版本,這個版本可以允許向next函式傳遞引數,指定取出幾個值。
#!/usr/bin/env python
#coding: utf-8
class
iterlist:
def__init__
(self, elem):
self.iter =iter(elem)
def__iter__
(self):
return
self
def next(self, howmany=1):
result =
for i in
range(howmany):
try:
except
stopiteration:
raise
return
result
if__name__ == '
__main__':
s = range(20)
test =iterlist(s)
test.next()
test.next()
print test.next(3)
這個例子能夠讓我們更加清晰的認識到next函式的工作原理。
用迭代器實現斐波那契數列
我們再給出最後乙個關於斐波那契數列的例子:
對於斐波那契數列,我們可以這樣實現:
deffab(max):
n, a, b = 0, 0, 1l =
while n a, b = b, a +b
n = n + 1
returnlif
__name__ == '
__main__':
for i in fab(5):
print i
上面的fab函式返回乙個列表,記錄斐波那契數列的值。
但是,當max過大的時候,fab就必須生成乙個巨大的列表,這不僅占用大量記憶體,也會消耗過多的時間。
下面我們使用迭代器,給出乙個更加高效的實現:
classfab(object):
def__init__
(self, max):
self.max =max
self.n, self.a, self.b = 0, 0, 1
def__iter__
(self):
return
self
defnext(self):
if self.n r =self.b
self.a, self.b = self.b, self.a +self.b
self.n = self.n + 1
return
r
raise
stopiteration()
if__name__ == '
__main__':
for i in fab(5):
print i
這個版本高效在何處?
之前的版本是預先把乙個巨大的結果生成,然後逐個去遍歷,而這裡呼叫fab時,僅僅做了乙個簡單的初始化工作,真正的計算則是發生在每次迭代呼叫next的時候。所以這裡不會占用過大的記憶體,而且不需要預先計算,也節約了時間。
本文最後部分參考了:
Python中Iterator迭代器的使用雜談
迭代器是一種支援next 操作的物件。它包含一組元素,當執行next 操作時,返回其中乙個元素 當所有元素都被返回後,生成乙個stopiteration異常。a 1,2,3 ia iter a next ia 1 next ia 2 next ia 3 next ia traceback most ...
python中迭代器詳解
1 迭代器是乙個可以記住遍歷的位置的物件。2 迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。3 迭代器有兩個基本的方法 iter 和next 4 字串,列表或元組物件都可用於建立迭代器 list 1,2,3,4 it iter list 建立迭代器物件 p...
python中迭代器 python中的迭代器
如果給定乙個list或tuple,我們可以通過for迴圈來遍歷這個list或tuple,這種遍歷我們稱為迭代 iteration d for key in d print key ac b當我們使用for迴圈時,只要作用於乙個可迭代物件,for迴圈就可以正常執行,而我們不太關心該物件究竟是list還...