一:什麼是迭代器協議python
1.迭代器協議是指:對象必須提供一個next方法,執行該方法要麼返回迭代器中的下一項,要麼就引發一個stoplteration異常,以終止協議(只能日後走不能往前)app
2.可迭代對象:實現了迭代器協議的對象(如何實現:對象內部定義一個_iter_()方法)函數
3.協議是一種約定,可迭代對象實現了迭代器協議,python的內部工具(如for循環,sum,min函數等)使用迭代器協議訪問對象。工具
二:for循環機制spa
1.for循環機制的本質:循環全部對象,所有都是使用迭代器協議。code
三:什麼是生成器對象
1.生成器,能夠理解爲一種數據類型,這種數據類型自動實現了迭代器協議(其餘的數據類型須要調用本身內置的_iter_方法),因此生成器就是可迭代對象。blog
2.生成器分類:在python中有兩種表現形式(python有兩種不一樣的方式提供生成器)內存
【1】生成器函數:常規函數定義,可是,使用yield語句而不是return語句返回結果,yield語句一次返回一個結果,在每一個結果中間,掛起函數的狀態,以便於下次從它離開的地方繼續執行。generator
1 def test(): 2 yield 1 3 yield 2 4 yield 3 5 res=test() 6 print(res) 7 print(res.__next__()) 8 print(res.__next__()) 9 #結果:<generator object test at 0x0000023E254BD8E0> 10 # 1 11 # 2
【2】生成器表達式:相似於列表推導,可是生成器返回按需產生結果的一個對象,而不是一次構建一個結果列表。
1 laomuji=('雞蛋%d' %i for i in range(10)) 2 print(laomuji) 3 print(laomuji.__next__()) 4 print(laomuji.__next__()) 5 print(laomuji.__next__()) 6 print(next(laomuji)) 7 print(next(laomuji)) 8 #結果:<generator object <genexpr> at 0x0000015F1262D8E0> 9 # 雞蛋0 10 # 雞蛋1 11 # 雞蛋2 12 # 雞蛋3 13 # 雞蛋4
3.列表解析:
1 egg_list=[] 2 for i in range(10): 3 egg_list.append('雞蛋%d' %i) 4 print(egg_list) 5 #結果:['雞蛋0', '雞蛋1', '雞蛋2', '雞蛋3', '雞蛋4', '雞蛋5', '雞蛋6', '雞蛋7', '雞蛋8', '雞蛋9'] 6 7 列表解析: 8 l=['雞蛋%d' %i for i in range(10)] 9 print(l) 10 #結果:['雞蛋0', '雞蛋1', '雞蛋2', '雞蛋3', '雞蛋4', '雞蛋5', '雞蛋6', '雞蛋7', '雞蛋8', '雞蛋9'] 11 #列表解析將即將生成的列表結果放前面,for循環放在後面 12 13 三元表達式:(三個操做,for循環前面是一個,for循環是一個,if條件這是一個) 14 l1=['雞蛋%d' %i for i in range(10) if i>5 ] 15 print(l1) 16 #結果:['雞蛋6', '雞蛋7', '雞蛋8', '雞蛋9'] 17 #沒有四元表達式
總結:
1.把列表解析的[]換成()獲得的就是生成器表達式
2.列表解析與生成器表達式都是一種便利的變成方式,只不過生成器表達式更加節省內存
3.Python不但使用迭代器協議讓for循環更加通用。大部份內置函數也是使用迭代器協議訪問對象的。例如,sum函數是Python的內置函數,該函數使用迭代器協議訪問對象,而生成器實現了迭代器協議,因此,咱們能夠直接計算一系列值得和:
1 sum(x**2 for x in range(4))
而不用畫蛇添足的先構造一個列表:
1 sum([x**2 for x in range(4)])