迭代器 一、什麼是迭代器 二、為何要有迭代器,什麼是可迭代對象,什麼是迭代器對象 三、迭代器對象的使用 四、for迴圈 五、迭代器的優缺點 優點:1.提供一種統一的,不依賴於索引的迭代方式 2.懶性計算,每次只有一條數據,節省記憶體 缺點:1.無法獲取長度(只有在迭代完畢才能知道有多少值) 2.一次性 ...
迭代器
一、什麼是迭代器
#迭代器即迭代的工具,那什麼是迭代呢? #迭代是一個重覆的過程,每次重覆即一次迭代,並且每次迭代的結果都是下一次迭代的初始值 while True: #只是單純地重覆,因而不是迭代 print('===>') l=[1,2,3] count=0 while 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 #True print(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 3 obj=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可以保存函數執行的狀態