什麼是迭代器?
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_dic2: 執行iter_dic.__next__()或是next(iter_dic),將得到的值賦值給i,然後執行迴圈體**(類似上面的while迴圈)
3: 重複過程2,直到捕捉到異常stopiteration,結束迴圈
重要的是for迴圈in後面的物件一定得是可迭代物件!!!
迭代器的優缺點:優點: 提供不依賴於索引的取值方式
惰性計算,節省記憶體,這裡可以去列印迭代器看看,
只有next的時候才計算值
缺點: 無法獲取長度(只有在next完畢才知道到底有幾個值),列印迭代器看到的是乙個位址
一次性的,只能往後走,不能往前退(只能一條道走到黑,回不到從前了)
生成器是什麼呢?
生成器是一種迭代器(可以自定義的迭代器),特性:迭代一次生成乙個值。我們得到乙個生成器呢,這裡有一種方式:
定義乙個函式,其內部包含有yield關鍵字,那麼呼叫一下得到的結果就是生成器,並且不會執行函式內部**
defget():
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 迭代器和生成器
迭代器是訪問集合元素的一種方式。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退,不過這也沒什麼,因為人們很少在迭代途中往後退。另外,迭代器的一大優點是不要求事先準備好整個迭代過程中所有的元素。迭代器僅僅在迭代到某個元素時才計算該元素,而在這之前或之後,元素可...