迭代器: 定義:更新換代的過程 每次迭代都必須基於上一次的的結果 器:迭代取值的工具 特色:不依賴索引取值 迭代取值的數據類型:字符串,列表,元組,字典,集合 一,可迭代對象 1,可迭代對象:只有內置有__iter__方法的都叫作可迭代對象 2,是可迭代對象的有: str list tuple dict set 文件對象(執行內置的__iter__以後仍是自己 沒有任何變化) 文件對象自己就是迭代器對象 案例: res = s.__iter__() # res = iter(s) print(s.__len__()) # 簡化成了len(s) res1 = l.__iter__() # res1 = iter(l) res2 = f1.__iter__() # res2 = iter(f1) 重點:可迭代對象執行內置的__iter__方法獲得就是該對象的迭代器對象 二:迭代器對象 1,內置有__iter__方法 2,內置有__next__方法 (進行取值) 注意:迭代器對象必定是可迭代對象 而可迭代對象不必定是迭代器對象 必須知足1,2 兩個條件纔是迭代器對象 1》生成一個可迭代對象 l = [1,2] res = l.__iter__() # 就是把一個可迭代對象用.__iter__()方法生成迭代器對象 2》迭代器取值 調用 __next__() print(res.__next__()) # 1 # 調用依次取出一個元素(迭代器對象中有幾個元素就能夠調用幾回) 直到取完,就會報錯StopIteration 案列: f1 = open('xxx.txt','r',encoding='utf-8') 調用f1內置的__iter__方法 iter_f = f1.__iter__() print(iter_f is f1) # 判斷iter_f 是否是 f1 ,打印 True 或者 False 重點:1,迭代器對象的取值必須用 __next__() 2,迭代器對象不管執行多少次__iter__方法,獲得的仍是迭代器對象自己 # print(f1 is f1.__iter__().__iter__().__iter__().__iter__()) 3. 迭代器取值的特色: 只能日後依次取值,不能倒着取 **注意:4,可迭代對象轉爲迭代對象用一次 .__iter__() 就可,屢次調用和第一次調用同樣(能夠理解爲初始化) 5,調用一次.__next__()方法只能取出其中一個元素,(列表爲第一個值,字典取出的是key) 總結: 可迭代對象:內置有__iter__方法的 迭代器對象: 既 內置有__iter__ 也內置有__next__方法 迭代取值:優勢:不依賴索引取值 內存中始終都佔一份空間,不會致使內存溢出 缺點 1.不可以獲取指定的元素,只能從前日後依次取 2.取完以後會報StopIteration錯 案例:1,文件取值案列 (假如文件中有一行內容,若是有n行就調用n次iter_f.__next__() f = open('xxx.txt','r',encoding='utf-8') iter_f = f.__iter__() print(iter_f.__next__()) 2,可迭代對象取值(list,dict,set,tuple,str) l = [1,2,3,4] iter_l = l.__iter__() print(iter_l.__next__()) # 1 l2 = {'name':'jason'} iter_l2 = l2.__iter__() print(iter_l2.__next__()) # name l3 = (3,'sr',[1,2],{1,'sc'}) iter_l3 = l3.__iter__() print(iter_l3.__next__()) # 3 print(iter_l3.__next__()) # sr print(iter_l3.__next__()) # [1, 2] print(iter_l3.__next__()) # {1, 'sc'} 其中的元素是什麼類型,取出來的也是該數據類型 三:for循環的本質: for i in d: # for循環後面的in關鍵 跟的是一個可迭代對象 1.將in後面的對象調用__iter__轉換成迭代器對象 2.調用__next__迭代取值 3.內部有異常捕獲StopIteration,當__next__報這個錯 自動結束循環 四:生成器: 用戶自定義的迭代器,本質就是迭代器 1,函數內有yield關鍵字存在時,函數名加括號不會運行函數體的代碼塊 而是將它轉變爲生成器,當用.__next__() 方法時纔會走函數體代碼 2,函數體代碼運行遇到yield 就會暫停運行 3,yield後面跟的值就是調用迭代器__next__方法你能獲得的值 ******** 4, yield既能夠返回一個值也能夠返回多個值 而且多個值也是按照元組的形式返回 5,yield 支持外界爲其傳參,多個值時 是以元組的形式返回 案列: def func(): print('egon not is dsb') yield 'no' print('天上飛來一隻猴') yield '666' g = func() # 生成器初始化:將函數變成迭代器 g.__next__() ## egon not is dsb print(g.__next__()) #天上飛來一隻猴 666 注意:函數體代碼中有 yield,當函數名加括號調用時, 他就是將函數轉變爲了自定義的生成器,並不會當即執行函數體代碼 案列: def func(name): print('%s 準備開吃'%name) while True: food = yield print('%s 吃了 %s'%(name,food)) g = func('egon') g.__next__() # 必須先將代碼運行至yield 纔可以爲其傳值 #egon 準備開吃 g.send('每天向上') # 給yield左邊的變量傳參 觸發了__next__方法 # egon 吃了 每天向上 g.send('好好學習') #egon 吃了 好好學習 2,生成器表達式: res = (i for i in range(1,100000000) if i != 4) # 生成器表達式 print(res) 1,生成器不會主動執行任何一行代碼 2,必須經過__next__觸發代碼的運行zcf 四:內置函數 divmod 分頁器 print(divmod(101,10) enumerate 枚舉 exec(s) eval(s) eval不支持邏輯代碼 format 三種玩法 {}佔位 {index} 索引 {name} 指名道姓 isinstance 後面統一改方法判斷對象是否屬於某個數據類型 n = 1 print(type(n)) print(isinstance(n,list)) # 判斷對象是否屬於某個數據類型 l = [0,1,0] print(all(l)) # 只要有一個爲False就返回False print(any(l)) # 只要有一個位True就返回True補充: 異常處理: while True: try: print(iter_d.__next__()) except StopIteration: print( ’取完了,沒有了') break