python提高1 遞迴和迭代,迭代器協議,生成器,生產者和消費者
阿新 • • 發佈:2022-05-23
一,遞迴和迭代的感念
# def test(): # #####################一,遞迴和迭代的感念##################### # print('遞迴就是:一層一層下去,找到了在一層一層返回') # print('迭代就是:找到一層,沒找到,在找下一下層,直到找到') # test()遞迴和迭代的感念
二,迭代器協議
1,迭代器協議定義
# # def test1(): # # ###########1,迭代器協議定義####### # # print('就是物件必須提供一個next方法,執行該方法要麼返回迭代器的下一項,要麼就引起一個\1,迭代器協議定義# # StopAsyncIteration異常,以終止迭代(只能往後走不能往前退)') # # test1()
2,迭代器物件
# def test2(): # # ###########2,迭代器物件####### # # print('實現了迭代器協議的物件(如何實現:物件內部定義一個__iter__()方法)') # # test2()2,迭代器物件
3,協議
# # ###########3,協議####### # # print('協議是一種約定,可迭代物件實現了迭代器協議\3,協議# # ,python(如for迴圈sum,min,max函式等)使用迭代器協議訪問物件') # # test3()
4,要用for迴圈的好處
def test4(): # ###########4,字串,列表,字典都不是可迭代物件?####### # print('因為字串,列表,字典。。都沒有__next__方法 ,\ # 那怎麼迴圈的,用了一個_iter__變成了可迭代物件,__next__') # v={'name':'qyl','age':19,'xb':'男'}.values().__iter__() # print(v)#<list_iterator object at 0x0000000001E91160>變成了可迭代物件了4,要用for迴圈的好處# print(v.__next__()) # print(v.__next__()) # print(v.__next__()) # k = {'name': 'qyl', 'age': 19, 'xb': '男'}.keys().__iter__() # print(k) # <list_iterator object at 0x0000000001E91160>變成了可迭代物件了 # print(k.__next__()) # print(k.__next__()) # print(k.__next__()) # # print(k.__next__())#遍歷光了就報錯 # with open('只讀模式.txt','r+',encoding='utf8',newline='') as f: # print(f.__iter__())#只是拿到一個記憶體地址 # print(f.__next__(),end="")#這樣就不損耗記憶體了(f.__next__()==next(f)) # print(f.__next__(),end="")#這樣就不損耗記憶體了 # with open('只讀模式.txt', 'r+', encoding='utf8', newline='') as f: # print(f.__iter__()) # 只是拿到一個記憶體地址 # while 1: # try: # print(f.__next__(), end="") # 這樣就不損耗記憶體了 # except StopIteration: # # print(" \n檔案已讀光")#捕捉StopIteration提示for就是沒提示直接break # break # test4()
三,生成器
生成器也是一個數據型別,自動實現了_iter_方法,說以生成器就是一個迭代器
# # def test1(): # # ##########1,生成器函式########## # # # 就是函式裡面有yield的就是生成器函式 # # def den(): # # print('sadasfasf') # # print('sadasfasf1') # # yield 1#有yield就是生成器函式,可以遍歷 # # print('sadasfasf2') # # print('sadasfasf3') # # yield 12 # # yield 13 # # scq=den()#必須要賦值才能變成生成器,才能變成迭代器 # # while 1: # # try: # # print(scq.__next__())#地2次next就是從第一次那個yield開始運行了 # # except StopIteration: # # break # # # for i in scq: # # # print(i) # # test1()1,生成器函式
2,生成器表示式
# # def test2(): # # ##########2,生成器表示式########## # # print('(1),三元表示式') # # def sy(): # # ##########(1),三元表示式########## # # # 就是中間有個判斷語句,為True 結果放在前面 ,為fales 結果放在後面面 # # name="qyl" # # res='qyl' if name=="qyl" else 'qjq' # # print(res) # # sy() # # print('(2),列表解析') # # def lbjx(): # # ##########(2),列表解析########## # # # 就是把列表的for迴圈簡化,缺點就是佔記憶體 # # # li=[] # # # for i in range(10): # # # if i>=5: # # # li.append('雞蛋%s'%i) # # # print(li) # # # 簡化成列表解析 # # li=['雞蛋%s'%i for i in range(10) if i>=5] # # print(li) # # lbjx() # # print('(3),生成器表示式') # # def lbjx(): # # ##########(3),生成器表示式########## # # # 就是把列表解析[]變成()好處就是變數變成迭代器不佔記憶體 # # li = ('雞蛋%s' % i for i in range(10) if i >= 5) # # for i in li: # # print(i) # # lbjx() # # test2()2,生成器表示式
3,計算總人口
# def pople_rk(): # with open("人口.txt",'r',encoding="utf8",newline='') as f: # for p in f: # yield p # pp=pople_rk() # all1=sum(eval(i)["人口"] for i in pp) # print(all1)3,計算總人口
四,生產者和消費者
1, send用法
# def test1(): # # #1, send(1)用法:1給yield 賦值給res # # #######1, send用法######### # # def scz(): # # print('開始生產包子.....') # # res=yield 'jg1的值' # # print("send的傳過來的值"%res) # # print('又開始生產包子.....') # # res1 = yield '又做了一籠包子' # # print(res1) # # scz() # # jg=scz()#jg是一個生成器 # # jg1=jg.__next__()#jg1是一個返回值 # # print(jg1) # # jg2=jg.send("吃了一籠包子") # # print(jg2) # # test1()1, send用法
2, 生產者和消費者
# def test2(): # # #######2, 生產者和消費者######### # # #2, 生產者和消費者就是實現併發效果 # # import time # # # 消費者 # # def a(name): # # print("開始執行A") # # while 1: # # time.sleep(1) # # res=yield "執行%s"%name # # print(res) # # #生產者 # # def b(): # # a1=a(a) # # a1.__next__() # # for i in range(10): # # time.sleep(1) # # a1.send("執行a1[第%s次]"%i) # # b() # # test2()2, 生產者和消費者