1. 程式人生 > 實用技巧 >迭代器和可迭代

迭代器和可迭代

所有的迭代器都是可迭代的

迭代器模式

實現一個自定義的迭代器模式需要兩個類,分別為實現了__iter__方法的類和通過__iter__返回的迭代器例項類(實現了__iter__和__next__方法)。下面例子簡單實現了上述功能。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class IterText: def __init__(self, text): self.text = text def __iter__(self): return IteratorText(self
.text) class IteratorText: def __init__(self, text): self.text = text self.index = 0 def __iter__(self): return self def __next__(self): try: letter = self.text[self.index] except IndexError: raise StopIteration self.index += 1 return letter text = IterText("hey") for l in text: print(l)

可迭代的IterText實現了__iter__方法,返回了迭代器IteratorText例項。IteratorText實現了__next__方法返回下一個迭代元素直到丟擲異常,同時IteratorText實現了__iter__方法返回自身物件用於迭代。

這裡的IterText和IteratorText很容易混淆,如果在IterText中實現了__next__方法並將__iter__中返回自身例項self也可以實現上述功能,但通常可迭代物件和迭代器應當分開,這樣在可迭代物件中的__iter__中可以返回不同的迭代器物件,使功能獨立。

生成器(generator)

通過上述文章說明,迭代器通過next()不斷產出下一個元素直到迭代器耗盡,而Python中的生成器可以理解為一個更優雅的迭代器(不需要實現__iter__和__next__方法),實現了迭代器協議,它也可以通過next()產出元素。
Python中的生成器主要分為兩種型別:

生成器函式(generator function)返回得到的生成器:

包含yield關鍵字的函式稱為生成器函式

Python標準庫中存在著一些可迭代物件,例如:list, tuple, dict, set, str等。

編譯器若想迭代一個物件a,則會自動呼叫iter(a)獲取該物件的迭代器(iterator),如果iter(a)丟擲異常,則物件a不可迭代。

判斷物件是否可迭代

原生函式iter(instance) 可以判斷某個物件是否可迭代,它的工作流程大概分為以下3個步驟:

  • 檢查物件instance是否實現了__iter__方法,並呼叫它獲取返回的迭代器(iterator)。
  • 如果物件沒有實現__iter__方法,但是實現了__getitem__方法,Python會生成一個迭代器。
  • 如果上述都失敗,則編譯器則丟擲TypeError錯誤,‘xxx' Object is not iterable。