迭代器和可迭代物件

2021-09-12 05:46:42 字數 4578 閱讀 1883

本篇文章簡單談談可迭代物件,迭代器和生成器之間的關係。

三者簡要關係圖

可迭代物件與迭代器

剛開始我認為這兩者是等同的,但後來發現並不是這樣;下面直接丟擲結論:

1)可迭代物件包含迭代器。

2)如果乙個物件擁有__iter__方法,其是可迭代物件;如果乙個物件擁有next方法,其是迭代器。

3)定義可迭代物件,必須實現__iter__方法;定義迭代器,必須實現__iter__和next方法。

你也許會問,結論3與結論2是不是有一點矛盾?既然乙個物件擁有了next方法就是迭代器,那為什麼迭代器必須同時實現兩方法呢?

因為結論1,迭代器也是可迭代物件,因此迭代器必須也實現__iter__方法。

介紹一下上面涉及到的兩個方法:

1)iter()

該方法返回的是當前物件的迭代器類的例項。因為可迭代物件與迭代器都要實現這個方法,因此有以下兩種寫法。

寫法一:用於可迭代物件類的寫法,返回該可迭代物件的迭代器類的例項。

寫法二:用於迭代器類的寫法,直接返回self(即自己本身),表示自身即是自己的迭代器。

也許有點暈,沒關係,下面會給出兩寫法的例子,我們結合具體例子看。

2)next()

返回迭代的每一步,實現該方法時注意要最後超出邊界要丟擲stopiteration異常。

下面舉個可迭代物件與迭代器的例子:

[python] view plain copy

#!/usr/bin/env python

class mylist(object): # 定義可迭代物件類

def __init__(self, num):  

self.data = num # 上邊界

def __iter__(self):

return mylistiterator(self.data) # 返回該可迭代物件的迭代器類的例項

class mylistiterator(object): # 定義迭代器類,其是mylist可迭代物件的迭代器類

def __init__(self, data):  

self.data = data # 上邊界

self.now = 0 # 當前迭代值,初始為0

def __iter__(self):

return self # 返回該物件的迭代器類的例項;因為自己就是迭代器,所以返回self

def next(self): # 迭代器類必須實現的方法

while self.now < self.data:

self.now += 1

return self.now - 1 # 返回當前迭代值

raise stopiteration # 超出上邊界,丟擲異常

my_list = mylist(5) # 得到乙個可迭代物件

print type(my_list) # 返回該物件的型別

my_list_iter = iter(my_list) # 得到該物件的迭代器例項,iter函式在下面會詳細解釋

print type(my_list_iter)

for i in my_list: # 迭代

print i

#!/usr/bin/env python12

345coding=utf-8

class mylist(object): # 定義可迭代物件類

definit(self, num):

self.data = num # 上邊界

defiter(self):

return mylistiterator(self.data) # 返回該可迭代物件的迭代器類的例項12

345class mylistiterator(object): # 定義迭代器類,其是mylist可迭代物件的迭代器類

definit(self, data):

self.data = data # 上邊界

self.now = 0 # 當前迭代值,初始為0

defiter(self):

return self # 返回該物件的迭代器類的例項;因為自己就是迭代器,所以返回self

def next(self): # 迭代器類必須實現的方法

while self.now < self.data:

self.now += 1

return self.now - 1 # 返回當前迭代值

raise stopiteration # 超出上邊界,丟擲異常12

3456

78910

1112

my_list = mylist(5) # 得到乙個可迭代物件

print type(my_list) # 返回該物件的型別

my_list_iter = iter(my_list) # 得到該物件的迭代器例項,iter函式在下面會詳細解釋

print type(my_list_iter)

for i in my_list: # 迭代

print i

執行結果:

問題:上面的例子**現了iter函式,這是什麼東西?和iter方法有關係嗎?

其實該函式與迭代是息息相關的,通過在python命令列中列印「help(iter)」得知其有以下兩種用法。

用法一:iter(callable, sentinel)

不停的呼叫callable,直至其的返回值等於sentinel。其中的callable可以是函式,方法或實現了call方法的例項。

用法二:iter(collection)

1)用於返回collection物件的迭代器例項,這裡的collection我認為表示的是可迭代物件,即該物件必須實現iter方法;事實上iter函式與iter方法聯絡非常緊密,iter()是直接呼叫該物件的iter(),並把iter()的返回結果作為自己的返回值,故該用法常被稱為「建立迭代器」。

2)iter函式可以顯示呼叫,或當執行「for i in obj:」,python直譯器會在第一次迭代時自動呼叫iter(obj),之後的迭代會呼叫迭代器的next方法,for語句會自動處理最後丟擲的stopiteration異常。

通過上面的例子,相信對可迭代物件與迭代器有了更具體的認識,那麼生成器與它們有什麼關係呢?下面簡單談一談

生成器生成器是一種特殊的迭代器,生成器自動實現了「迭代器協議」(即__iter__和next方法),不需要再手動實現兩方法。

生成器在迭代的過程中可以改變當前迭代值,而修改普通迭代器的當前迭代值往往會發生異常,影響程式的執行。

看乙個生成器的例子:

[python] view plain copy

#!/usr/bin/env python

def mylist(num): # 定義生成器

now = 0 # 當前迭代值,初始為0

while now < num:

val = (yield now) # 返回當前迭代值,並接受可能的send傳送值;yield在下面會解釋

now = now + 1 if val is none else val # val為none,迭代值自增1,否則重新設定當前迭代值為val

my_list = mylist(5) # 得到乙個生成器物件

print my_list.next() # 返回當前迭代值

print my_list.next()

my_list.send(3) # 重新設定當前的迭代值

print my_list.next()

print dir(my_list) # 返回該物件所擁有的方法名,可以看到__iter__與next在其中

#!/usr/bin/env python12

345coding=utf-8

def mylist(num): # 定義生成器

now = 0 # 當前迭代值,初始為0

while now < num:

val = (yield now) # 返回當前迭代值,並接受可能的send傳送值;yield在下面會解釋

now = now + 1 if val is none else val # val為none,迭代值自增1,否則重新設定當前迭代值為val

my_list = mylist(5) # 得到乙個生成器物件

print my_list.next() # 返回當前迭代值

print my_list.next()

my_list.send(3) # 重新設定當前的迭代值

print my_list.next()

print dir(my_list) # 返回該物件所擁有的方法名,可以看到iter與next在其中

執行結果:

具有yield關鍵字的函式都是生成器,yield可以理解為return,返回後面的值給呼叫者。不同的是return返回後,函式會釋放,而生成器則不會。在直接呼叫next方法或用for語句進行下一次迭代時,生成器會從yield下一句開始執行,直至遇到下乙個yield。

可迭代物件和迭代器

建立這個物件的類中是否定義了 iter 方法,如果定義了,那麼這個物件就是可迭代物件。isinstance obj,iterable 判斷 判斷乙個物件是不是迭代器的時候,需要判斷建立這個例項物件的類中是否定義了 iter 方法和 next 方法,如果都定義了,那麼這個物件就是可迭代物件。所以如果乙...

可迭代物件和迭代器

實現了 iter 方法的物件稱為可迭代物件,在python中,可迭代物件有字串 列表 元組 字典 集合等 class mynumbers def init self self.a 1 def iter self return self my numbers mynumbers 判斷物件是否是可迭代物...

可迭代物件和迭代器

迭代器即迭代的工具,那什麼是迭代呢?迭代是乙個重複的過程,每次重複即一次迭代,並且每次迭代的結果都是下一次迭代的初始值 while true 只是單純地重複,因而不是迭代 print l 1,2,3 count 0 while count len l 迭代 print l count count 1...