迭代器
迭代器即迭代的工具,那什麼是迭代呢?
迭代是一個重複的過程,每次重複即一次迭代,而且每次迭代的結果都是下一次迭代的初始值編程
優勢:app
一、爲什麼要有迭代器?ide
對於序列類型:字符串、列表、元組,咱們能夠使用索引的方式迭代取出其包含的元素。但對於字典、集合、文件等類型是沒有索引的,若還想取出其內部包含的元素,則必須找出一種不依賴於索引的迭代方式,這就是迭代器函數
二、什麼是可迭代對象?工具
可迭代對象指的是內置有iter方法的對象,即obj.iter,以下code
'hello'.__iter__ (1,2,3).__iter__ [1,2,3].__iter__ {'a':1}.__iter__ {'a','b'}.__iter__ open('a.txt').__iter__
三、什麼是迭代器對象?對象
可迭代對象執行obj.iter()獲得的結果就是迭代器對象
而迭代器對象指的是即內置有iter又內置有next方法的對象索引
文件類型是迭代器對象 open('a.txt').__iter__() open('a.txt').__next__()
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
#基於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,結束循環
生成器
#只要函數內部包含有yield關鍵字,那麼函數名()的到的結果就是生成器,而且不會執行函數內部代碼 def func(): print('====>first') yield 1 print('====>second') yield 2 print('====>third') yield 3 print('====>end') g=func() print(g) #<generator object func at 0x0000000002184360>
yield總結內存
一、把函數作成迭代器
二、對比return,能夠返回屢次值,能夠掛起/保存函數的運行狀態字符串
name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' print(res)
優勢:方便,改變了編程習慣,可稱之爲聲明式編程
egg_list=[] for i in range(10): egg_list.append('雞蛋%s' %i) egg_list=['雞蛋%s' %i for i in range(10)]
#一、把列表推導式的[]換成()就是生成器表達式 #二、示例:生一筐雞蛋變成給你一隻老母雞,用的時候就下蛋,這也是生成器的特性 >>> chicken=('雞蛋%s' %i for i in range(5)) >>> chicken <generator object <genexpr> at 0x10143f200> >>> next(chicken) '雞蛋0' >>> list(chicken) #因chicken可迭代,於是能夠轉成列表 ['雞蛋1', '雞蛋2', '雞蛋3', '雞蛋4',] #三、優勢:省內存,一次只產生一個值在內存中
def xd(): for i in range(100): yield '雞蛋%s' %i s=xd() print(s.__next__()) print(s.__next__())