python學習筆記之八 迭代器和生成器

2022-02-06 10:54:15 字數 2906 閱讀 3103

一. 迭代器

在前面的筆記中,已經提到過迭代器(和可迭代),這裡會對此進行深入討論。只討論乙個特殊方法---__iter__,這個方法是迭代器規則的基礎。

1.1 迭代器規則

迭代的意思是重複做一些事情很多次,到現在為止只是在for迴圈中對序列和字典進行迭代,但實際上也能對其他的物件進行迭代:實現__iter__方法的物件。

__iter__方法返回乙個迭代器,所謂迭代器就是具有next方法(這個方法在呼叫時不需要任何引數)的物件。在呼叫next方法時,迭代器會返回它的下乙個值。如果next方法被呼叫,但迭代器沒有值可以返回,就會引發乙個stopiteration異常。

為什麼不用列表?列表是一次性獲取所有值的,如果有很多值,列表會占用太多的記憶體,但是迭代器可以在使用時計算乙個值時獲取乙個值,使用迭代器更通用,簡單,優雅。

下面來看乙個不使用列表的例子:

__metaclass__ =type

class

fibs:

def__init__

(self):

self.a =0

self.b =0

defnext(self):

self.a,self.b = self.b,self.a +self.b

return

self.a

def__iter__

(self):

return self

注意:迭代器實現了__iter__方法,這個方法實際上返回迭代器本身。很多情況下,__iter__會放到其他的會在for迴圈中使用的物件中。這樣一來,程式就能返回所需的迭代器。此外,推薦使用迭代器實現它自己的_iter__方法,然後就能直接在for迴圈中使用迭代其本身了。

>>> f =fibs()

>>> for n in

f:

if n > 10:

print

n

break

13

1.2 從迭代器得到序列

除了在迭代器和可迭代物件上進行迭代外,還能把它們轉換為序列。在大部分能使用序列的情況下,能使用迭代器替換。關於這個的乙個很有用的例子是使用list構造方法顯式地將迭代器轉化為列表。

__metaclass__ =type

class

testiterator:

value =0

defnext(self):

self.value += 1

if self.value > 10:raise

stopiteration

return

self.value

def__iter__

(self):

return self

>>> ti =testiterator()

>>>list(ti)

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

二. 生成器

生成器是python新引入的概念,由於歷史原因,它也叫簡單生成器。它和迭代器可能是近幾年來引入的最強大的兩個特性。生成器可以幫助讀者寫出非常優雅的**。

生成器是一種用普通的函式語法定義的迭代器。讓我們先看看怎麼建立和使用生成器,然後再了解一下她的內部機制。

2.1 建立生成器

首先建立乙個展開巢狀列表的函式,引數是乙個列表的列表,類似於nested = [[1,2],[3,4],[5]],函式按照順序列印出列表中的數字:

__metaclass__ =type

defflatten(nested):

for sublist in

nested:

for element in

sublist:

yield element

這個函式首先迭代提供的巢狀列表中的所有子列表,然後按順序迭代列表中的元素。yield語句是新知識,任何包含yield語句的函式都稱為生成器。它不像return那樣返回值,而是每次產生多個值。每次產生乙個值,函式就會被凍結:即函式停在那點等待被啟用,函式被啟用後就從停止的那點開始執行。

接下來可以通過在生成器上迭代來使用所有的值:

>>> nested = [[1,2],[3,4],[5]]

>>> for num in

flatten(nested):

print

num 12

345

2.2 遞迴生成器

上面的例子中只能處理兩層巢狀,如果不知道有多少層巢狀呢?我們就要求助於遞迴了:

__metaclass__ =type

defflatten(nested):

try:

for sublist in

nested:

for element in

sublist:

yield

element

except

typeerror:

yield nested

當flatten被呼叫時,有兩種可能性:基本情況和需要遞迴的情況,在特殊情況中,展開的是乙個列表,程式必須遍歷所有的字列表,並對他們呼叫flatten。然後用另乙個for迴圈來產生被展開的子列表中的所有元素。

>>> nested = [[1,2],[3,4],[5,[6,[7]]]]

>>> for num in flatten(nested):

print num12

345[6, [7]]

(上面的結果跟書《python基礎教程(第二版)》中例子的結果不一樣,我也搞不懂)

Python學習筆記 迭代器

from collections import iterable from collections import iterator 可迭代物件 可以直接作用於for迴圈的物件統稱為可迭代物件 iterable 可以用isinstance 去判斷乙個物件是否是iterable物件 可以直接作用於for...

python學習之迭代器

在介紹迭代器時候,首選介紹兩個概念,from collections.abc import iterable from collections.abc import iterator print isinstance iterable print isinstance iterable print ...

python學習之迭代器

4.5.1 可迭代物件 字面意思分析 可以重複的迭代的實實在在的東西。list,dict keys values items tuple,str,set,range,檔案控制代碼 待定 專業角度 內部含有 iter 方法的物件,就是可迭代物件。內建函式 dir print dir str 判斷乙個物...