day11 Python 迭代器
迭代器
我們之前一直在用可迭代物件進行迭代操作. 那麼到底什麼是可迭代物件. 本小節主要討論可迭代物件. ⾸先我們先回顧一下⽬前我們所熟知的可迭代物件有哪些:
str, list, tuple, dict, set. 那為什麼我們可以稱他們為可迭代物件呢? 因為他們都遵循了可迭代協議. 什麼是可迭代協議. ⾸先我們先看一段錯誤程式碼:
# 對的 s = "abc" for c in s: print(c) # 錯的 for i in 123: print(i) # TypeError: 'int' object is not iterable
注意看報錯資訊中有這樣一句話. 'int' object is not iterable . 翻譯過來就是數型別物件是不可迭代的. iterable表⽰可迭代的. 表⽰可迭代協議. 那麼如何進⾏驗證你的資料型別是否符合可迭代協議. 我們可以通過dir函式來檢視類中定義好的所有⽅法.
在列印結果中. 尋找 如果能找到__iter__ ,那麼這個類的物件就是⼀個可迭代物件.
s = "我的哈哈哈" print(dir(s)) # 可以列印物件中的⽅法和函式 print(dir(str)) # 也可以列印類中宣告的方法和函式
我們發現在字串串中可以找到__iter__. 繼續看⼀一下list, tuple, dict, set;我們發現這⼏個可以進⾏for迴圈的東⻄都有__iter__函式, 包括range也有. 可以自⼰試⼀下.
這是檢視一個物件是否是可迭代物件的第一種辦法. 我們還可以通過isinstence()函式來檢視一個物件是什麼型別的。
綜上. 我們可以確定. 如果物件中有__iter__函式. 那麼我們認為這個物件遵守了可迭代協議. 就可以獲取到相應的迭代器. 這⾥的__iter__是幫助我們獲取到物件的迭代器. 我們使⽤迭代器中的__next__()來獲取到⼀個迭代器中的元素. 那麼我們之前講的for的⼯作原理理到底是什麼? 繼續看程式碼。
l = [1,2,3] l_iter = l.__iter__() from collections import Iterable from collections import Iterator print(isinstance(l,Iterable)) #True print(isinstance(l,Iterator)) #False print(isinstance(l_iter,Iterator)) #True print(isinstance(l_iter,Iterable)) #True s = "我愛北北京天安⻔門" c = s.__iter__() print(c.__next__()) print(c.__next__()) print(c.__next__()) print(c.__next__()) print(c.__next__()) print(c.__next__()) print(c.__next__()) print(c.__next__())
# 獲取迭代器器
# 使⽤迭代器器進行迭代. 獲取一個元素
#我
#愛
#北
#京
#天
#安
#⻔
# StopIteration
for迴圈的機制:
for i in [1,2,3]: print(i)
使⽤用while迴圈+迭代器來模擬for迴圈(必須要掌握)
lst = [1,2,3] lst_iter = lst.__iter__() while True: try: i = lst_iter.__next__() print(i) except StopIteration: break
總結:
Iterable: 可迭代物件. 內部包含__iter__()函式
Iterator: 迭代器. 內部包含__iter__() 同時包含__next__(). 迭代器的特點:
1. 節省記憶體.
2. 惰性機制
3. 不能反覆, 只能向下執行.
for迴圈的時候. ⼀開始的 時候是__iter__()來獲取迭代器. 後⾯每次獲取元素都是通過__next__()來完成的. 當程式遇到 StopIteration將結束迴圈.