Python 全棧開發:python迭代器,產生器,python產生器
迭代器一、什麼是迭代器
#迭代器即迭代的工具,那什麼是迭代呢?#迭代是一個重複的過程,每次重複即一次迭代,並且每次迭代的結果都是下一次迭代的初始值while True: #只是單純地重複,因而不是迭代 print('===>') l=[1,2,3]count=0while count < len(l): #迭代 print(l[count]) count+=1二、為何要有迭代器,什麼是可迭代對象,什麼是迭代器對象
#1、為何要有迭代器?對於序列類型:字串、列表、元組,我們可以使用索引的方式迭代取出其包含的元素。
但對於字典、集合、檔案等類型是沒有索引的,若還想取出其內部包含的元素,則必須找出一種不依賴於索引的迭代方式,這就是迭代器#2、什麼是可迭代對象?可迭代對象指的是內建有__iter__方法的對象,即obj.__iter__,如下'hello'.__iter__(1,2,3).__iter__[1,2,3].__iter__{'a':1}.__iter__{'a','b'}.__iter__open('a.txt').__iter__#3、什麼是迭代器對象?可迭代對象執行obj.__iter__()得到的結果就是迭代器對象而迭代器對象指的是即內建有__iter__又內建有__next__方法的對象檔案類型是迭代器對象open('a.txt').__iter__()open('a.txt').__next__()#4、注意:迭代器對象一定是可迭代對象,而可迭代對象不一定是迭代器對象
三、迭代器對象的使用
dic={'a':1,'b':2,'c':3}iter_dic=dic.__iter__() #得到迭代器對象,迭代器對象即有__iter__又有__next__,但是:迭代器.__iter__()得到的仍然是迭代器本身iter_dic.__iter__() is iter_dic #Trueprint(iter_dic.__next__()) #等同於next(iter_dic)print(iter_dic.__next__()) #等同於next(iter_dic)print(iter_dic.__next__()) #等同於next(iter_dic)# print(iter_dic.__next__()) #拋出異常StopIteration,或者說結束標誌#有了迭代器,我們就可以不依賴索引迭代取值了iter_dic=dic.__iter__()while 1: try: k=next(iter_dic) print(dic[k]) except StopIteration: break #這麼寫太醜陋了,需要我們自己捕捉異常,控制next,python這麼牛逼,能不能幫我解決呢?能,請看for迴圈四、for迴圈
#基於for迴圈,我們可以完全不再依賴索引去取值了dic={'a':1,'b':2,'c':3}for k in dic: print(dic[k])#for迴圈的工作原理#1:執行in後對象的dic.__iter__()方法,得到一個迭代器對象iter_dic#2: 執行next(iter_dic),將得到的值賦值給k,然後執行迴圈體代碼#3: 重複過程2,直到捕捉到異常StopIteration,結束迴圈五、迭代器的優缺點
優點:1.提供一種統一的,不依賴於索引的迭代方式
2.懶性計算,每次只有一條資料,節省記憶體
缺點:1.無法擷取長度(只有在迭代完畢才能知道有多少值)
2.一次性的,順序移動,無法後退
產生器一、什麼是產生器
函數內包含yield的關鍵字,在調用函數時不會執行內部代碼,得到的函數傳回值就是一個產生器對象
def chicken(): print('=====>first') yield 1 print('=====>sencond') yield 2 print('=====>third') yield 3obj=chicken()print(obj) #<generator object func at 0x > 產生器對象二、產生器就是迭代器
產生器本質就是迭代器,也就是說產生器的玩法其實就是迭代器的玩法
obj.__iter__obj.__next__#2、所以產生器就是迭代器,因此可以這麼取值res=next(obj)print(res)
模仿range() 功能
def my_range(start,stop,step=1): while start < stop: yield start start+=step
for item in my_range(1,10,2): print(item)
# 結果 :1,3,5,7,9
三、總結yield
#1、為我們提供了一種自訂迭代器的方式,# 可以在函數內用yield關鍵字,調用函數拿到的結果就是一個產生器,產生器就是迭代器#2、yield可以像return一樣用於傳回值,區別是return只能返回一次值,而yield可返回多次# 因為yield可以儲存函數執行的狀態