Python編程:迭代器協(xié)議與遍歷,輕松搞定
前言
前篇內容的介紹應該能很容易地讓我們理解掌握??Python中的可迭代對象和迭代器(Iterable & Iterator)??。本次內容我們來進一步介紹迭代器的有關內容。

迭代器協(xié)議
在Python中,迭代器(Iterator)對象需要支持以下兩個方法,它們一起構成迭代器協(xié)議:
1)__iter__():
對象的該方法返回迭代器對象本身。這是要求容器和迭代器與for-in語句一起使用所必需的。你也可以使用內置的iter()函數(shù),該函數(shù)實質上是在背后調用了__iter__()方法的。
2)__next__():
從迭代器中返回下一項。如果沒有其他項,則拋出StopIteration異常。也可以使用內置的next()函數(shù)讀取下一項,其實質也是調用__next__()方法。
正如我們在前所講過的,列表、元組、字典和集合都是可迭代類型。換句話說,它們是可以從中獲得迭代器的類型??词纠?

代碼片段清單-01
輸入結果如下:
在示例代碼中,我們定義了一個可迭代元組。然后對這個可迭代對象調用iter()函數(shù)。iter()函數(shù)返回一個迭代器,我們將其命名為tupIter。然后多次調用next()函數(shù)。next()函數(shù)每次執(zhí)行時,都會自動返回迭代器中的下一項。
再看下一段示例代碼:

代碼片段-02
運行輸出的結果為:
在上述代碼清單中,在字符串對象上調用__ iter__()方法。字符串對象實現(xiàn)了迭代器協(xié)議,所以字符串是包含字符序列的可迭代對象的。直接調用__ iter__()方法就可返回一個迭代器。然后再通過返回的迭代器調用__ next__()方法,就可一個一個地輸出迭代器中的元素內容。
一言以蔽之,只要實現(xiàn)了迭代器協(xié)議的對象,即可按照上面的兩種方法進行對象的迭代調用。
迭代器遍歷
正如我們在前介紹中看到的,我們使用next()函數(shù)(或__next__()方法)手動遍歷迭代器的項。當next()函數(shù)到達迭代器的末尾時,就沒有更多的數(shù)據(jù)要返回,將得到一個StopIteration異常。
請看示例:

代碼片段清單-03
運行上述程序,輸出結果類似如下:
10 20 30 Traceback (most recent call last): File ……, in <module> print(next(listIter)) StopIteration |
在上述代碼中,調用了next()函數(shù)四次,這比迭代器中的項數(shù)還要多。在最后一個調用中得到了拋出的StopIteration異?!驗榈鲀仍仨椧呀浀炅?。而且,為保證手動迭代完成后可能拋出的異常,得自行進行異常處理,否則后續(xù)將不再正常執(zhí)行。
需要認識到的是:絕大多數(shù)場景下,我們不需要自己手動調用next方法,Python中的for循環(huán)能夠自動遍歷任何可以返回迭代器的對象。換句話說,for循環(huán)可以遍歷Python中的任何可迭代對象。
請看示例:

代碼清單片段04
在上述代碼中,我們使用for循環(huán)遍歷前面定義的列表。顯而易見,我們沒有手動使用next()函數(shù),也沒有獲得任何StopIteration異常。這就是Python中for循環(huán)的美妙之處。它在幕后為我們處理所有這些。
當然,我們可以自行這樣來處理循環(huán)迭代?,F(xiàn)在定義一個我們自己的for循環(huán)版本。我們將使用while循環(huán)并復制for循環(huán)的行為。在此,我們自己構建該實現(xiàn)所需的一切。如下所示:

代碼清單片段-05
在上述清單中,我們實現(xiàn)了自己版本的模擬for循環(huán)。代碼中使用無限while循環(huán):while True。在循環(huán)中設置了一個try-except塊。在try塊中,通過調用迭代器上的__next__()方法獲得下一個元素。如果調用成功,則打印出該元素。如果發(fā)生了StopIteration類型的錯誤,則在except塊中捕獲該異常。在except塊中所做的事情非常簡單。我們只是跳出這個循環(huán),這意味著我們已經到達迭代器的末端。
小結
本篇內容就寫這些了,主要介紹了迭代器協(xié)議和和迭代器遍歷。內容的文字不長,再結合代碼能幫助你更好地理解和掌握這些Python編程知識點。




























