Python 入門基礎11 --函數基礎4 叠代器、生成器、枚舉類型
阿新 • • 發佈:2019-04-03
不依賴 ria factorial 完成 func data- except spl 技術
今日目錄:
-
1.叠代器
-
2.可叠代對象
-
3.叠代器對象
-
4.for循環叠代器
-
5.生成器
-
6.枚舉對象
一、叠代器:
循環反饋的容器(集合類型)
每次重復即一次叠代,並且每次叠代的結果都是下一次叠代的初始值
l = [1, 2, 3] count = 0 while count<len(l): print(l[count]) count += 1View Code
1.1 為什麽要有叠代器?
字符串、列表、元組可以通過索引的方式叠代取出其中包含的元素
字典、集合、文件等類型,沒有索引,只有通過不依賴索引的叠代方式才能取值,即叠代器
二、可叠代對象
2.1 什麽是可叠代對象
可叠代對象指的是內置有__iter__()方法的對象,即obj.__iter__()
str,list,tuple,dict,set,range(),file,叠代器對象,enumerate(),生成器都是可叠代對象,即: [].__iter__() {}.__iter__() ().__iter__() {1,2}.__iter__() ......View Code
三、叠代器對象
3.1 什麽是叠代器對象
可叠代對象通過調用__iter__()方法得到叠代器對象
叠代器對象可以不依賴索引取值(一次從容器中取出一個值)
叠代器對象都有__next__方法,且通過該方法獲取容器中的值,獲取規則,從前往後一次一個
3.2 有哪些叠代器對象
文件類型、enumerate()、生成器是叠代器對象
open(‘a.txt‘).__iter__()
open(‘a.txt‘).__next__()
ps:
1.叠代器對象去一個值就少一個值
2.取完了再取會報錯 --> 可通過try對異常進行捕獲,並處理
3.上一個叠代器對象叠代取值完畢後,就取空了,如果要再取值,要重新生成叠代器對象
4.叠代器對象不能求長度(內部值的個數)
5.叠代器對象一定是可叠代對象,而可叠代對象不一定時叠代器對象
# 叠代器對象 iter_obj = st1.__iter__View Code() print(iter_obj) # <set_iterator object at 0x0000025B85231CF0> print([1, 2, 3].__iter__()) # <list_iterator object at 0x0000017694B0B860> # 叠代器對象去一個值就少一個值 print(iter_obj.__next__()) # 9 print(iter_obj.__next__()) # 2 print(iter_obj.__next__()) # 3 print(iter_obj.__next__()) # 4 print(iter_obj.__next__()) # 7 # print(iter_obj.__next__()) # 7 # 異常 StopIteration
# 叠代器無法求長度(內部值的個數) while True: try: val = iter_obj2.__next__() print(val) except StopIteration: breakView Code
四、for 循環叠代器
自帶異常處理的while循環,自動獲取被叠代的對象的叠代器對象
原理:
1.執行in後面對象的dic.__iter__()方法,得到一個叠代器對象iter_dic
2.執行next(iter_dic),將得到的值賦值給k,然後執行循環體代碼
3.重復過程2,直到捕捉到異常,StopIteration,結束循環
叠代器的優缺點:
1.優點
提過一種統一的、不依賴於索引的叠代方式
惰性計算,節省內存
2.缺點
無法獲取長度(只有在next完畢才知道到底有幾個值)
一次性的,只能往後走,不能往前退
# for 循環叠代器,自帶異常處理的while循環,自動獲取被叠代的對象的叠代器對象 iter_obj = st1.__iter__() for item in iter_obj: print(item) print(‘----------------華麗的分割線-----------------------------------------------‘) for item1 in st1: # 自動完成for item in st1.__iter__() # 自動完成異常處理 print(item1)View Code
五、生成器
包含yield關鍵字的函數就是生成器
def fn():
yield ‘good‘
該函數名()得到的是生成器對象,且不會執行函數體
生成器的應用案例
當訪問的數據資源過大,可以將數據用生成器處理,一次只獲取所有內容的一條資源
def g_fn(): print("!!!!!!!!!!!!!!!!!!!!") yield ‘第一個‘ print(‘@@@@@@@@@@@@@@@@@@@@@‘) yield ‘第二個‘ print(‘#####################‘) yield ‘第三個‘ print(‘$$$$$$$$$$$$$$$$$$$$$‘) yield ‘第四個‘ g_obj = g_fn() # 在函數內部執行一次,在遇到下一個yield時停止,且可以拿到yield的返回值 r1 = g_obj.__next__() print(r1) # 從上一次停止的地方繼續往下走,再遇到下一個yield的時候停止,且可以拿到yield的返回值 r2 = g_obj.__next__() print(r2) r3 = g_obj.__next__() print(r3)View Code
# 重新定義一個range()生成器 def my_range(min, max, step=1): # min, max = max, min tag = min while True: if tag >= max: break yield tag tag += step range_obj = my_range(5, 10, 1) for i in range_obj: print(i)View Code
六、枚舉對象
通過for循環叠代器循環遍歷可叠代對象,需要知道叠代的索引
作業:
# 1.用生成器完成自定義range方法,可以完成系統range的所有功能 def my_range(min, max= 0, step=1): if step > 0: # 步長為正的 if max == 0: # 如果最大值為 0 --> my_range(10) min, max = max, min tag = min while True: if tag >= max: break yield tag tag += step elif step < 0: # 步長為負的 tag = min if min > max: while True: if tag <= max: break yield tag tag += step else: # 第三個參數不能是 0 print("第三個參數不能是 0 !") range_obj1 = my_range(10, 1, -2) range_obj2 = my_range(10) # --------可以用 range_obj3 = my_range(2, 10) # -----可以用 range_obj4 = my_range(2, 10, 2) # --可以用 """ for i in range_obj1: print(i) """View Code
# 2.用生成器完成自定義enumerate方法,也可以為可叠代對象提供索引支持 # ls = [4, 3, 7, 5, 9] ls = {1,2,3,4,5,6} def my_enumerate(data): count = 0 for i in data: yield (count, i) count += 1 """ for i, v in my_enumerate(ls): print(i, v) """View Code
# 3.用生成器完成獲取階乘得方法,第一次next得到1的階乘,第二次next得到2的階乘,依次類推, # 直接for循環,可以依次得到指定範圍內得所有階乘,eg:factorial(10),可以得到1~10之間的10個階乘 def my_factorial(num): tag = 1 for i in my_range(1, num+1): tag *= i yield tag factorial_obj = my_factorial(10) for i in factorial_obj: print(i) """ 1 2 6 24 120 720 5040 40320 362880 3628800 """View Code
Python 入門基礎11 --函數基礎4 叠代器、生成器、枚舉類型