到目前為止,您可能已經注意到大多數容器物件都可以使用 for 語句:
print(element)
for element in (1, 2, 3):
print(element)
for key in :
print(key)
for char in "123":
print(char)
for line in open("myfile.txt"):
print(line, end='')
這種訪問風格清晰、簡潔又方便。 迭代器的使用非常普遍並使得 python 成為乙個統一的整體。 在幕後,for 語句會呼叫容器物件中的 iter()。 該函式返回乙個定義了 __next__() 方法的迭代器物件,該方法將逐一訪問容器中的元素。 當元素用盡時,__next__() 將引發 stopiteration 異常來通知終止 for 迴圈。 你可以使用 next() 內建函式來呼叫 __next__() 方法;這個例子顯示了它的運作方式:
>>> s = 'abc'
>>> it = iter(s)
>>> it
>>> next(it)
'a'>>> next(it)
'b'>>> next(it)
'c'>>> next(it)
traceback (most recent call last):
file "", line 1, in next(it)
stopiteration
看過python迭代器協議的幕後機制,給你的類新增迭代器行為就很容易了。 定義乙個 __iter__() 方法來返回乙個帶有 __next__() 方法的物件。 如果類已定義了 __next__(),則 __iter__() 可以簡單地返回 self:
"""iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise stopiteration
self.index = self.index - 1
return self.data[self.index]
>>>
>>> rev = reverse('spam')
>>> iter(rev)
<__main__.reverse object at 0x00a1db50>
>>> for char in rev:
... print(char)
...map
s
python生成器
generator 是乙個用於建立迭代器的簡單而強大的工具。 它們的寫法類似標準的函式,但當它們要返回資料時會使用 yield 語句。 每次對生成器呼叫 next() 時,它會從上次離開位置恢復執行(它會記住上次執行語句時的所有資料值)。 顯示如何非常容易地建立生成器的示例如下:
for index in range(len(data)-1, -1, -1):
yield data[index]
>>>
>>> for char in reverse('golf'):
... print(char)
...flo
g
可以用生成器來完成的操作同樣可以用前一節所描述的基於類的迭代器來完成。 但生成器的寫法更為緊湊,因為它會自動建立 __iter__() 和 __next__() 方法。
另乙個關鍵特性在於區域性變數和執行狀態會在每次呼叫之間自動儲存。 這使得該函式相比使用 self.index 和 self.data 這種例項變數的方式更易編寫且更為清晰。
除了會自動建立方法和儲存程式狀態,當生成器終結時,它們還會自動引發 stopiteration。 這些特性結合在一起,使得建立迭代器能與編寫常規函式一樣容易。
生成器表示式
某些簡單的生成器可以寫成簡潔的表示式**,所用語法類似列表推導式,將外層為圓括號而非方括號。 這種表示式被設計用於生成器將立即被外層函式所使用的情況。 生成器表示式相比完整的生成器更緊湊但較不靈活,相比等效的列表推導式則更為節省記憶體。
例如:
>>> sum(i*i for i in range(10)) # sum of squares
285>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec)) # dot product
260>>> from math import pi, sin
>>> sine_table =
>>> unique_words = set(word for line in page for word in line.split())
>>> valedictorian = max((student.gpa, student.name) for student in graduates)
>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1, -1, -1))
['f', 'l', 'o', 'g']
腳注
[1] 存在乙個例外。 模組物件有乙個秘密的唯讀屬性dict__,它返回用於實現模組命名空間的字典;__dict是屬性但不是全域性名稱。 顯然,使用這個將違反命名空間實現的抽象,應當僅被用於事後偵錯程式之類的場合。
Python迭代器和生成器
先說迭代器,對於string list dict tuple等這類容器物件,使用for迴圈遍歷是很方便的。在後台for語句對容器物件呼叫iter 函式,iter 是python的內建函式。iter 會返回乙個定義了next 方法的迭代器物件,它在容器中逐個訪問容器內元素,next 也是python的...
Python迭代器和生成器
迭代器是訪問集合元素的一種方法 是可以記住遍歷的位置的物件。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問 他有兩個基本的方法,iter 和next 字串,列表或遠足物件都可以用於建立迭代器 list1 1,2,3,4 it1 iter list1 建立迭代器物件 print next ...
python 迭代器和生成器
迭代器是訪問集合元素的一種方式。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退,不過這也沒什麼,因為人們很少在迭代途中往後退。另外,迭代器的一大優點是不要求事先準備好整個迭代過程中所有的元素。迭代器僅僅在迭代到某個元素時才計算該元素,而在這之前或之後,元素可...