以下是Python文檔中對于迭代器類型的描述
Python有一個在容器上進行迭代的概念。其實現(xiàn)需要兩個方法來支持;這讓用戶自己定義的類也可以支持迭代。序列類型都支持迭代方法。
容器對象需要提供一個方法來提供對于迭代的支持:
container.__iter__():這個方法返回一個迭代器對象。這個對象必須支持后面所描述的迭代器協(xié)議。如果一個容器要支持不同類型的迭代,則可以提供額外的方法來專門為這些迭代類型請求相應(yīng)的迭代器。(對象支持多種迭代形式的一個例子就是樹數(shù)據(jù)結(jié)構(gòu)中對廣度優(yōu)先和深度優(yōu)先遍歷的支持)。這個方法對應(yīng)于Python/C API中Python對象類型結(jié)構(gòu)體中的tp_iter字段。
迭代器對象自身必須具有如下兩個方法,這兩個方法一起就構(gòu)成了迭代器協(xié)議:
iterator.__iter__()
返回迭代器對象自身。這是為了讓容器和迭代器都能支持for和in語句。這個方法對應(yīng)于Python/C API中Python對象類型結(jié)構(gòu)體中的tp_iter字段。
iterator.__next__()
返回容器中的下一個元素。如果沒有更多的元素了,就會拋出StopIteration異常。這個方法對應(yīng)于Python/C API中Python對象類型結(jié)構(gòu)體中的tp_iternext字段。
Python定義了幾種迭代器對象來支持對常規(guī)和特定序列類型、字典和其它特殊類型的迭代。特定類型主要地,就是實現(xiàn)了迭代器協(xié)議而已。
一旦迭代器的__next__()方法拋出了StopIteration異常,隨后的調(diào)用中也必須這樣做。不遵守此種行為的情況被視為迭代器已損壞。
以上是文檔中對迭代器類型相關(guān)的介紹,其中的核心就是迭代器對象——也就是實現(xiàn)了迭代器協(xié)議的對象。為此我們先根據(jù)文檔中的說明定義自己的一個迭代器:
class SimpleIterator:
def __init__(self, max_index, position=0):
self._position = position
self._max = max_index
def __iter__(self):
return self
def __next__(self):
current_position = self._position
if current_position <= self._max:
self._position += 1
return current_position
else:
raise StopIteration
if __name__ == '__main__':
simple_iterator = SimpleIterator(100)
for item in simple_iterator:
print(item)
這是一個非常簡單的迭代器,在其上迭代可以依次訪問從初始化的position到max_index的所有整型數(shù),并且是個閉區(qū)間(我在條件中使用了<=)。
現(xiàn)在我們實現(xiàn)了迭代器,如果想要讓容器支持迭代器協(xié)議,按照上面文檔的說法,就應(yīng)該在一個容器內(nèi)部定義一個__iter__()方法,并且要求其返回一個迭代器對象,我寫了一個簡單的支持迭代的容器類,它可以支持正序和反序迭代容器中的內(nèi)容:
class ReverseIterator:
def __init__(self, seq=[]):
self._seq = seq
self._current_index = len(self._seq) - 1
def __iter__(self):
return self
def __next__(self):
if self._current_index < 0:
raise StopIteration
use_index = self._current_index
self._current_index -= 1
return self._seq[use_index]
class SimpleContainer:
def __init__(self, seq=[], reverse=False):
self._seq = seq
self._reverse = reverse
def __iter__(self):
if not self._reverse:
return iter(self._seq)
else:
return ReverseIterator(self._seq)
if __name__ == '__main__':
print("reverse=False")
simple_container = SimpleContainer([1, 2, 3], reverse=False)
for item in simple_container:
print(item)
print("reverse=True")
simple_container = SimpleContainer([1, 2, 3], reverse=True)
for item in simple_container:
print(item)
這里面,我使用了iter內(nèi)置函數(shù)用來獲取list類型的迭代器,用來支持默認的正序迭代;為了支持反序迭代,我自己實現(xiàn)了一個迭代器,根據(jù)容器的創(chuàng)建參數(shù),容器的__iter__()方法會返回不同類型的迭代器,以支持不同類型的迭代。
最后,幾點總結(jié):
- __iter__()方法總是返回迭代器對象;
- __next__()方法需要在迭代器中返回下一個值;
- 迭代器對象中的__iter__()方法主要目的是為了讓迭代器對象自身也支持for和in語句;
- 可以根據(jù)容器設(shè)置的條件,指定使用不同類型的迭代器;
- 要避免在迭代器協(xié)議實現(xiàn)的過程中復(fù)制底層容器對象(比如通過list[::-1]表達式來獲取一個反序的新列表),防止內(nèi)存資源浪費;
以上。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
