第十三天-生成器
阿新 • • 發佈:2018-11-02
# 生成器:
# 生成器實質就是迭代器(省記憶體 惰性機制 只往前)
# 1. 通過生成器函式
# 2. 通過各種推導式來實現生成器
# def func():
# yield
#
# g = func() - 得到生成
1 # 生成器函式 就是把return 換成yield 2 # return 換成 yield 理解成一次性執行 只往前 3 def fu(): 4 print("娃哈哈") 5 yield "哈哈娃" # yield可以把函式分段執行 6 print("AD鈣") 7 yield "美滋滋" 8 print("爽歪歪") 9 10 # fu() # 這裡是獲取到生成器物件 generator 不會執行函式 11 print(fu()) # 輸出 生成器 generator 12 ret = fu() 13 print(ret.__next__()) # 必須執行__next__()才可以觸發生成器的執行 娃哈哈 14 print(ret.__next__()) # 必須執行__next__()才可以觸發生成器的執行 美滋滋 15 print(ret.__next__()) # StopIteration 迭代器 找不到 yield 報錯
# 生成器的用法和迭代器基本一致
# __next__() 開始執行生成器 . 執行到yield. 直到沒有yield. 丟擲StopIteration
# 生成器函式有什麼用
# 省記憶體
1 # 如定製一萬衣服 一次性全輸出了 全堆到公司沒地放 2 # 普通程式會很佔記憶體 3 # def buy(): 4 # lis = [] 5 # for i in range(10000): 6 # lis.append("衣服%s"%i) 7 # return lis 8 # 9 # print(buy()) 10 11 #生成器 要多少拿多少 12 # 省記憶體 13 # def buy(): 14 # lis = [] 15 # for i in range(1,10000): 16 # lis.append("衣服%s"%i) 17 # if i % 50 == 0: # 50一批次得拿 18 # yield lis 19 # lis = [] # 每次生成一個新列表(新批次) 20 # 21 # set = buy() # 獲取到生成器 22 # print(set.__next__()) # 拿到第一批1-50 23 # print(set.__next__()) # 拿到第二批51-100 24 # print(set.__next__()) 25 # print(set.__next__())
# 生成器還可以用 __next__() snd()來訪問生成器
# send()給上一個yield位置 傳值
1 def food(): 2 print("水餃") 3 a = yield "大餡水餃" 4 print("a=", a) 5 print("燒餅") 6 b = yield "武大郎燒餅" 7 print("b=", b) 8 print("老婆餅") 9 c = yield "只要老婆不要餅" 10 print("c=", c) 11 12 # 使用__next__()來訪問生成器 13 ret = food() # 生成器 14 # print(ret.__next__()) # 執行第一個yield 水餃 大餡水餃 15 # print(ret.__next__()) # 執行第二個yield 燒餅 武大郎燒餅 16 # print(ret.__next__()) # 執行第三個yield 老婆餅 只要老婆不要餅 17 18 # 使用 send()來訪問生成器 # send()有__next__的作用 但還會返回值給 yield 19 print("返回值是:",ret.__next__()) 20 print("返回值是:",ret.send("來兩盤")) # 給第一個 a 和__next__()一樣也是向下找yield. 但還給上一個yield傳值 21 print("返回值是:",ret.send("來五張")) # 返回給了第2個 yield 即b 22 print("返回值是:",ret.send("來一堆!")) # 返回給了第3個 yield 即c 23 24 # send()不可以在第一個位置和最後一個位置出現 25 # 最後的yield後的程式碼是可以執行的但是會報錯. StopIteration
# 生成器函式裡不要寫return
1 def func(): 2 print("哈哈") 3 yield "呵呵" 4 print("吼吼") 5 return "嘻嘻" # don't do this! 6 7 gen = func() 8 gen.__next__() 9 gen.__next__()
# 列表推導式
# 語法 [結果 for迴圈 if判斷]
# 要得到的效果必須放前面的結果位置
1 lis = ["運動會%s期"% i for i in range(0,18)] 2 print(lis) 3 4 lis1 = [i for i in range(0,21) if i%2==1] 5 print(lis1) 6 7 lst = ["中島美雪", "夏川美里", "原由子", "汪峰", "田震","那英","周杰倫"] 8 9 lst1 = [i for i in lst if len(i)== 2 ] 10 print(lst1) 11 12 lis = [i**2 for i in range(1,21) if i%2==1] 13 print(lis)
1 # 已知(3,6,9) 2 # 輸出(1,2,3) (4,5,6) (7,8,9) 3 # 4 lis = [3,6,9] 5 lis1 = [] 6 for i in lis: 7 lis1.append((i-2,i-1,i)) 8 print(lis1) 9 10 # 用推導式 11 lis1 = [(i-2,i-1,i) for i in lis] 12 print(lis1) 13 14 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'], 15 ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] 16 17 for i in names: 18 for j in i: 19 if j.count("e")==2: 20 print(j) 21 # 推導式 22 name1 = [j for i in names for j in i if j.count("e") == 2] 23 print(name1)
# 字典推導式
# 語法 {結果 for迴圈 if判斷}
#
1 # dic = {"張無忌":"趙敏", "楊過":"小龍女", "郭靖":"黃蓉"} 2 # dic1 = {dic[i]:i for i in dic} 3 # print(dic1) 4 #
# 集合推導式 # 不可變 不重複 無序的
# {結果 for迴圈 if判斷}
# set = {i*堅挺 for i in range(1,11)}
# 生成器表示式
# 語法 (結果 for迴圈 if判斷) # 沒有元祖推導式!
# 特點: 本質是迭代器 __next__()
# 省記憶體
# 惰性機制
# 只能往前
1 # 坑(面試題)生成器函式 2 def fun(): 3 print(111) 4 yield 222 5 6 g = fun() 7 g1 = (i for i in g) # 沒有__next__() 不執行 8 g2 = (i for i in g1) 9 10 print(list(g)) 11 print(list(g1)) 12 print(list(g2))