1、迭代器協議是指:對象必須提供一個next()方法,執行該方法要么返回迭代中的下一項,要么引起一個StopIteration異常,以終止迭代(只往后走,不能往前退----》模擬人更新換代)
2、可迭代對象:實現可迭代協議的對象。(對象內部定義一個__iter__()方法)
3、協議是一種約定,可迭代對象實現了可迭代協議,python的內部工具(如for sum max min...函數)使用迭代器 協議訪問對象。
for循環的本質:循環所有對象,全部都使用迭代器協議。
for循環就是基於迭代器協議提供了一個統一的可遍歷所有對象的方法,即在遍歷之前,先調用對象的__iter__()方法將其轉換為一個迭代器,然后使用迭代器協議去實現循環訪問,這樣所有對象都可以通過for循環來遍歷了。
列表、字符串、元組、字典、集合、文件對象等本質上都不是可迭代對象,在使用for循環時內部先調用他們內部的__iter__方法,使它們變為一個可迭代對象,然后使用可迭代對象的next(可迭代對象)方法或者 對象.__next__(),依次循環元素,當元素循環完時,會觸發StopIteration異常,for循環會捕捉到這種異常,終止迭代。
1 # _*_ encoding:utf-8 _*_ 2 __author__ = 'listen' 3 __date__ = '2018/11/19 22:10' 4 # li=[1,2,3,4,5] #通過下標索引方式取 只試用於有序的 列表 元組 字符串 不適用無序字典 集合 5 # print(li[0]) #1 6 # print(li[1]) #2 7 # print(li[2]) #3
1 #通過迭代器訪問 2 # li=[1,2,3,4,5,6] 3 # iter_li=li.__iter__() #通過__iter__()方法 生成一個可迭代對象 4 # print(iter_li.__next__()) #1 可迭代對象就有__next__()方法 一個一個取值 5 # print(iter_li.__next__()) #2 6 # print(iter_li.__next__()) #3 7 # print(iter_li.__next__()) 8 # print(iter_li.__next__()) 9 # print(iter_li.__next__()) 10 # print(iter_li.__next__()) #StopIteration,超出邊界報錯
1 #for 循環訪問的本質==遵循迭代器訪問方式,先調用iter_l=li.__iter__()方法,然后依次執行iter_l.__next__(),直到for循環捕捉到StopIteration終止循環 2 # li=[1,2,3,4,5] 3 # for i in li: 4 # print(i) 5 6 7 #用while去模擬for循環做的事情 8 # li=[1,2,3,4,5] 9 # index=0 10 # while index<len(li): 11 # print(li[index]) 12 # index+=1 13 14 15 #next()和__next__()方法是相同的 16 # li=[1,2,3] 17 # iter_li=li.__iter__() 18 # print(iter_li.__next__()) #1 19 # print(next(iter_li)) #2
定義:生成器類似於一種數據類型,這種數據類型自動實現迭代器協議(其他的數據類型都需要調用自身的__iter__方法),所以生成器就是可迭代對象。
1、生成器函數:和常規函數沒什么區別,但使用yield語句返回結果 而不是return,yield語句一次返回一個結果,但每個結果中間,掛起函數的狀態,以便下次從它離開的地方繼續執行。
2、生成器表達式:類似於列表推導式,但是生成器返回按需產生的結果的一個對象(類似內存的一個地址),而不是一次構建結果的列表,按需取對象。
使用生成器的優點:
python使用生成器對延遲操作提了支持。所謂延遲操作,是指需要的時候才產生結果,而不是立即產生結果,節省內存,運行效率高,這是生成器的主要好處。
三元表達式:f=if取出的結果 if條件 else else結果
列表解析:s=[三元表達式],列表解析生成的是一個真實存在的列表,對於比較大的列表,消耗內存比較大。
count=[x for x in range(3)]
生成器表達式1:s=(三元表達式),區別於列表解析是 [] 到 ()
count=(x for x in range(3)) #生成器本身就是迭代器,遵循迭代器協議
1 #生成器----一種數據類型,這種數據類型自動實現迭代器協議(其他數據類型(字典 list tuple等等)都需要調用內置的__iter__()方法),所以生成器就是可迭代對象 2 3 4 #1、生成器函數 yield 代替return語句返回 可以調用多次 5 # def fun(): 6 # yield 1 #可迭代對象 7 # yield 2 8 # yield 3 9 # f=fun() 10 # print(f.__next__()) #1 11 # print(f.__next__()) #2 12 # print(f.__next__()) #3 13 # print(f.__next__()) ##執行只能一直往前走,不能往后,只能執行一次,執行完繼續執行會觸發StopIteration 14 15 16 17 #2、生成器表達式 18 #三元表達式 result=值1 if 條件 else 值2 列表表達式=[]是真實存在內存中的列表,對於大的列表特別消耗內存 19 # count=[x for x in range(3)] #三元表達式 20 # count=(x for x in range(3)) #生成器 21 # sum(x for x in range(3)) ##sum函數是Python的內置函數,該函數使用迭代器協議訪問對象,而生成器實現了迭代器協議,不用多此一舉先生成列表 22 23 #雞下蛋 24 laomuji=('雞蛋%s'%i for i in range(9) if i<5) 25 print(laomuji) #<generator object <genexpr> at 0x00000221029D1C50> 這是一個可迭代對象就不會占用很大的內存 26 print(laomuji.__next__()) 27 print(laomuji.__next__()) 28 print(laomuji.__next__()) 29 print(laomuji.__next__()) 30 print(laomuji.__next__()) 31 print(next(laomuji)) #StopIteration拋異常
生成器只能往后走,不能往前退,且只能執行一次。
1 # _*_ encoding:utf-8 _*_ 2 __author__ = 'listen' 3 __date__ = '2018/11/20 21:14' 4 # #執行只能一直往前走,不能往后,只能執行一次 5 # def test(): 6 # for i in range(4): 7 # yield i 8 # t=test() 9 # t1=(i for i in t) 10 # t2=(i for i in t1) 11 # print(list(t1)) #list()就是在執行next方法 for也是在執行next方法 [0, 1, 2, 3] 12 # print(list(t2)) # [] t1的數據取完了,沒有了,所以list(t2)為空
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。