亚洲日本欧美日韩高观看,性高湖久久久久久久久,亚洲av成人噜噜无码网站,亚洲欧美日韩国产一区二区动图,亚洲欧美日韩国产精品一区二区


學(xué)AI,好工作 就找北大青鳥
關(guān)注小青 聽課做題,輕松學(xué)習(xí)
周一至周日
4000-9696-28

Python中的迭代器與可迭代對(duì)象

來(lái)源:北大青鳥總部 2023年01月13日 11:01

摘要: Python中的許多結(jié)構(gòu)內(nèi)置支持可迭代協(xié)議,會(huì)自動(dòng)處理StopIteration異常,如for循環(huán)、拆包等。

說(shuō)到Python編程語(yǔ)言,最令人印象深刻的應(yīng)該就是它的易用性了。為了提供易用性,語(yǔ)言中封裝了大量的常用數(shù)據(jù)結(jié)構(gòu)、算法和類庫(kù),并創(chuàng)建了不少

與其他語(yǔ)言不同的概念。其中,大部分概念都非常容易理解。然而,仍有些概念比較相似,常常使初學(xué)者混淆,比如迭代器和可迭代對(duì)象。

有編程經(jīng)驗(yàn)的開發(fā)者都知道,迭代(或稱循環(huán))是處理大量數(shù)據(jù)時(shí)非常常用的手段。


從普通對(duì)象到迭代器

查看下面一個(gè)常規(guī)的類定義:

class SimpleClass1:

pass

simple1 = SimpleClass1()

如果從simple對(duì)象獲取數(shù)據(jù):

next(simple1)

將會(huì)報(bào)錯(cuò)“TypeError: 'SimpleClass1' object is not an iterator”,這是因?yàn)閟imple1對(duì)象不是一個(gè)迭代器。


下面介紹Python中的可迭代協(xié)議。

如果要使一個(gè)對(duì)象成為一個(gè)迭代器,需要:

實(shí)現(xiàn)無(wú)參數(shù)的“__next__”方法,返回下一個(gè)數(shù)據(jù);

當(dāng)沒有下一個(gè)數(shù)據(jù)時(shí),拋出一個(gè)特殊的異常StopIteration。


那么,重新實(shí)現(xiàn)SimpleClass,如下:

class SimpleClass2:

def __init__(self, name):

self.name = name

self.current = 0

def __next__(self):

if self.current >= len(self.name):

raise StopIteration

nextval = self.name[self.current]

self.current += 1

return nextval

simple2 = SimpleClass2('abc')

重新使用next函數(shù)就可以獲取數(shù)據(jù)了:

next(simple2) # 返回a

next(simple2) # 返回b

next(simple2) # 返回c

next(simple2) # 拋出異常 StopIteration

如上所示,迭代器可以成功返回?cái)?shù)據(jù),如預(yù)期那樣。但是每次都使用next函數(shù)獲取數(shù)據(jù)還是比較麻煩,更不用說(shuō)還要去處理異常。


從迭代器到可迭代對(duì)象

如果在開發(fā)中,對(duì)象能夠直接支持for循環(huán)來(lái)進(jìn)行遍歷,并且自動(dòng)處理StopIteration異常,那么實(shí)際開發(fā)工作將會(huì)簡(jiǎn)單許多。

于是Python中引入了可迭代對(duì)象的概念,可迭代對(duì)象就是能夠支持使用iter來(lái)獲取迭代器的對(duì)象。我們可以在類中實(shí)現(xiàn)__iter__方法來(lái)支持iter函數(shù):

class SimpleClass3:

def __init__(self, name):

self.name = name

self.current = 0

def __next__(self):

if self.current >= len(self.name):

raise StopIteration

nextval = self.name[self.current]

self.current += 1

return nextval

def __iter__(self):

print('__iter__方法被調(diào)用')

return self

simple3 = SimpleClass3('abc')

使用for循環(huán)打印元素:

for item in simple3:

print(item)

將會(huì)順序輸出 a, b, c三個(gè)元素,for循環(huán)語(yǔ)句會(huì)自動(dòng)調(diào)用iter獲取此可迭代對(duì)象的迭代器,并自動(dòng)處理異常。


Python可迭代協(xié)議使用實(shí)例

以上就是Python中的可迭代協(xié)議。下面使用該協(xié)議仿照系統(tǒng)內(nèi)置range實(shí)現(xiàn)一個(gè)簡(jiǎn)化版本的類SimpleRange,它支持返回從0到n(不包括)的整數(shù)值。

class _SimpleRange:

def __init__(self, n):

self.n = n

self.current = 0

def __iter__(self):

return self

def __next__(self):

"""支持獲取下一個(gè)元素"""

if self.current >= self.n:

raise StopIteration # 當(dāng)沒有下一個(gè)元素時(shí)拋出異常

next_val = self.current # 保存當(dāng)前值以便返回

self.current += 1

return next_val


class SimpleRange:

"""簡(jiǎn)化版本的range"""

def __init__(self, n):

"""初始化對(duì)象"""

self.n = n

def __iter__(self):

"""支持返回迭代器"""

return _SimpleRange(self.n)


simple_range = SimpleRange(10)

r = range(10)

assert list(simple_range) == list(r)

assert list(simple_range) == list(r) # 該斷言會(huì)成功通過(guò)

上面的代碼中,_SimpleRange實(shí)現(xiàn)了__next__方法,所以其對(duì)象是一個(gè)迭代器。而SimpleRange實(shí)現(xiàn)了_iter__方法,并且在其中返回一個(gè)新的_SimpleRange對(duì)象。SimpleRange是一個(gè)可迭代對(duì)象。

需要注意的是,在SimpleRange對(duì)象中每次調(diào)用iter都會(huì)返回一個(gè)全新的迭代器(即_SimpleRange對(duì)象),這就是上面代碼中,第二個(gè)斷言能夠通過(guò)的原因。

下面看第二個(gè)例子,定義一個(gè)列表如下:

lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]

我們知道,lst是可迭代對(duì)象,所以可以使用iter函數(shù)獲取其迭代器iter(lst)。而如果將同一個(gè)迭代器放入zip函數(shù),可以同時(shí)分別從

同一個(gè)迭代器獲取數(shù)據(jù),即:

lst_iter = iter(lst)

assert list(zip(lst_iter, lst_iter, lst_iter)) == [(1, 2, 3), (4, 5, 6), (7, 8, 9)]

將上面的代碼組合在一起,配合拆包則可以使用代碼:

list(zip(*[iter(lst)]*3))

將列表 [1, 2, 3, 4, 5, 6, 7, 8, 9],轉(zhuǎn)換為 [(1, 2, 3), (4, 5, 6), (7, 8, 9)]。


特殊的可迭代對(duì)象

除了標(biāo)準(zhǔn)的實(shí)現(xiàn)可迭代的方法(即實(shí)現(xiàn)__iter__方法)外,如果一個(gè)類實(shí)現(xiàn)了__getitem__方法,并且其索引是從0開始的整數(shù),則

其對(duì)象也是可迭代對(duì)象。如:

class SimpleClass4:

def __init__(self, n):

self.n = n

def __getitem__(self, idx):

if idx < self.n:

return idx

raise StopIteration


總結(jié)

可迭代對(duì)象就是可以用來(lái)拿到迭代器的對(duì)象,而迭代器可以用來(lái)獲取下一個(gè)數(shù)據(jù)。

可迭代對(duì)象實(shí)現(xiàn)了返回迭代器的__iter__方法或者使用從0開始的整數(shù)索引的__getitem__方法;迭代器實(shí)現(xiàn)了獲取下一個(gè)元素的__next__方法,當(dāng)沒有下一個(gè)元素時(shí),迭代器會(huì)拋出一個(gè)特殊的異常StopIteration。

Python中的許多結(jié)構(gòu)內(nèi)置支持可迭代協(xié)議,會(huì)自動(dòng)處理StopIteration異常,如for循環(huán)、拆包等。

標(biāo)簽: python
報(bào)名優(yōu)惠
免費(fèi)試聽
課程資料
官方微信
返回頂部
培訓(xùn)課程 熱門話題 站內(nèi)鏈接