python迭代器和生成器

2022-04-23 14:57:02 字數 3662 閱讀 2369

什麼是迭代器?

python中為什麼會有迭代器,我們知道python中一些有索引的序列型別,如list,tuple,str,我們可以使用索引的方式迭代取出其包含的元素。

但對於字典、集合、檔案等型別是沒有索引的,若還想取出其內部包含的元素,則必須找出一種不依賴於索引的迭代方式,也就是它應該具有遍歷複雜資料結構的能力,這就是迭代器。

什麼是可迭代物件?

在python中可迭代物件指的是內建有__iter__方法的物件。

#

可迭代物件

l=[0,8]

dic=

l.__iter__

()dic.

__iter__()

什麼是迭代器物件?

在python中迭代器物件指的是即內建有__iter__又內建有__next__方法的物件

#

迭代器物件

with open('

ad.txt

','r

') as f:

f.__iter__

() f.

__next__()

可迭代物件和迭代器物件都有__iter__方法,那麼有什麼區別呢?
可迭代物件.__iter__()得到的是乙個迭代器物件
迭代器物件.__iter__()得到的仍然是迭代器物件本身

也就是說迭代器物件一定是可迭代物件,而可迭代物件不一定是迭代器物件

l=[0,8]

dic=

obj=l.__iter__

()obj1=dic.__iter__

()obj.

__next__

()obj.

__iter__

()obj1.

__next__

()obj1.

__iter__()#

迭代器物件

with open('

ad.txt

','r

') as f:

f1=f.__iter__

()

print(f1==f,f1 is f)#

這裡是true

f.__next__()

迭代器物件.__next__()方法是做什麼的呢

這裡的__next__()方法就是用來取值的

l=[0,8]#

l是可迭代物件

obj_l=l.__iter__()#

obj_l是迭代器物件

print(obj_l.__next__())#

輸出0print(obj_l.__next__())#

輸出8print(obj_l.__next__())#

報錯stopiteration

這裡我們沒有按索引取值,但是去拿到了列表l裡的值。那我們再來看看其他沒有索引的

dic=

iter_dic=dic.__iter__() #

先得到迭代器物件,不管是迭代器物件還是可迭代物件

print(iter_dic.__next__

())

print(next(iter_dic)) #

等同於iter_dic.__next__()

print(iter_dic.__next__()) #

當然這裡3個輸出會是無序的 ---->x y z

print(iter_dic.__next__()) #

再繼續就,丟擲異常stopiteration,或者說結束了

當然也可以用迴圈的方式取值

dic=

iter_dic=dic.__iter__()#

先得到迭代器物件,不管是迭代器物件還是可迭代物件

while

true:

try:

print(next(iter_dic)) #

等同於iter_dic.__next__() 取出來是dic的鍵

except

stopiteration:

break

上面的迴圈取值就跟python中的for迴圈一樣的

這裡我們可以了解一下for迴圈的機制:

dic=

for i in

dic:

print(i)

1:先執行in後物件的dic.__iter__()方法,得到乙個迭代器物件iter_dic

2: 執行iter_dic.__next__()或是next(iter_dic),將得到的值賦值給i,然後執行迴圈體**(類似上面的while迴圈)

3: 重複過程2,直到捕捉到異常stopiteration,結束迴圈

重要的是for迴圈in後面的物件一定得是可迭代物件!!!

迭代器的優缺點:

優點: 提供不依賴於索引的取值方式

惰性計算,節省記憶體,這裡可以去列印迭代器看看,

只有next的時候才計算值  

缺點: 無法獲取長度(只有在next完畢才知道到底有幾個值),列印迭代器看到的是乙個位址

一次性的,只能往後走,不能往前退(只能一條道走到黑,回不到從前了)

生成器是什麼呢?

生成器是一種迭代器(可以自定義的迭代器),特性:迭代一次生成乙個值。

我們得到乙個生成器呢,這裡有一種方式:

定義乙個函式,其內部包含有yield關鍵字,那麼呼叫一下得到的結果就是生成器,並且不會執行函式內部**
def

get():

print(222)

yield 2

print('

ada'

)

yield 3it=get()

print(it)#

print(it.__next__())#

222 2

print(it.__next__())#

ada 3

print(it.__next__())#

報錯stopiteration

這裡我們發現當我們呼叫生成器it的next方法時,它遇到yield才停下來,然後把yiled後的值返回來

繼續next的話會跳到下乙個yield 然後把yiled後的值返回來,若next下去的話沒有yield 則會報錯。

也就是說yield後的值在呼叫一次next時會被返回一次。

這樣的話我們就有操作空間了,對yield後的值進行自定義我們想要的,也就是可以自定義的迭代器。

仿寫乙個range的例子:

def my_range(start,end,step=1):

while start yield

start

start+=step

for i in my_range(0,22,3):

print(i)

當然yield還有其他用處,這裡的yield只是提供一種自定義迭代器的方式。

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 迭代器和生成器

迭代器是訪問集合元素的一種方式。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退,不過這也沒什麼,因為人們很少在迭代途中往後退。另外,迭代器的一大優點是不要求事先準備好整個迭代過程中所有的元素。迭代器僅僅在迭代到某個元素時才計算該元素,而在這之前或之後,元素可...