本節主要學習內容有兩點:python迭代器;for循環原理。
在介紹這兩點前我們要了解什么是可迭代對象,下面依次介紹之。
可迭代對象
可迭代對象(iterable)指的是可以依次返回其內部成員的對象。比如字符串、列表、字典、文件等都是可迭代對象。從語法方面說就是那些具有__iter__的方法的對象,對於類來說指的是那些具有__getitem__方法的對象。
迭代器
python一切皆對象,迭代器(iterator)也可以說是迭代器對象。具有__iter__方法的對象調用__iter__會返回一個迭代器對象。從語法上說就是那些同時具有__next__和__iter__方法的對象。
- 迭代器調用
__next__方法會調用迭代器中的下一個值; - 迭代器調用
__iter__方法返回迭代器本身;
# 迭代器對象表示一種數據流,會通過重復調用其__next__方法(同將其傳參給內置函數next)從數據流中返回一個元素;
# 當數據流中沒有數據元素時,就會拋出一個 StopIterationd的異常。
# 迭代器也有一個__iter__方法,也就是說迭代器也是一個可迭代對象,我們又知道迭代器調用其__iter__方法返回的是其迭代器本身;
# 這看起來是似乎是多余雞肋的,但如果從全局上看這樣做的好處是巨大了,它能夠讓迭代器使用的更靈活(在可迭代器的位置上也可以使用迭代器)
>>> s={1,2,3} # 可迭代對象s
>>> i=iter(s) # 本質就是在調用s.__iter__(),返回s的迭代器對象i,
>>> next(i) # 本質就是在調用i.__next__()
1
>>> next(i)
2
>>> next(i)
3
>>> next(i) #拋出StopIteration的異常,代表無值可取,迭代結束
python文件是一個可迭代對象,同時也是一個迭代器。
迭代器是Python提供的一種統一的、不依賴於索引的迭代取值方式,只要存在多個"值",無論序列類型還是非序列類型都可以按照迭代器的方式取值。
迭代器優缺點
優點:
- 為序列和非序列類型提供了一種統一的迭代取值方式;
- 惰性取值;每次只取一個數據,不占內存;迭代器保存的是產生數據的算法,而不是實際的數據。
缺點:
- 除非取盡,否則無法獲取迭代器的長度;
- 只能往后依次取值,不能返回頭往前取值。就像象棋中的卒,只進不退。
for循環原理
while循環是條件循環;for循環是迭代器循環;
剛開始接觸python流程控制的循環結構時,我們知道while循環可以實現for循環的所有功能,之所以使用for循環主要是使用其方便又強大的遍歷取值功能。for循環的這種遍歷取值功能本質上是利用了迭代器的原理。
# while + iterator
goods=['mac','lenovo','acer','dell','sony']
goods_iterator = iter(goods) # 等同於goods.__iter__()
while True:
try:
print(next(goods_iterator)) # 等同於goods.__next__()
except StopIteration: # 捕捉異常終止循環
break
# for循環
for i in goods:
print(i)
為什么for循環會如此簡潔?這是因為for循環底層我們做了:
- 第一,調用可迭代對象的
__iter__方法,將goods轉化為迭代器goods_iterator; - 第二,調用迭代器goods_iterator的
__next__方法,返回出goods的第一個元素; - 第三,循環步驟2,直到迭代器內數據流全部輸出,捕獲異常()
