隨堂筆記 19 day
阿新 • • 發佈:2018-03-11
ret 註意事項 with open 位置 ida none object 列表 模型
簡潔的列表解析形式 ----[ i for i in range(10) ]
生成器表達式 ----[ i for i in range(10) ]
自己的問題:
return和yield可以連用嗎? 不能,會報錯。
def test(): yield 1 yield 2 yield 3 res = test() print(res) #這樣是打印生成器,不是yield返回值 print(res.__next__()) #這樣才是打印yield返回值,調用next的方法 結果 <generator object test at 0x0000021CD6E99728> 1
next----觸發----yield
yield:
1.返回值
2.保留函數運行狀態,基於從上次yield的結束末尾開始
消費者和生產者模型
# 生產包子(100個) 第一種方法 def product_baozi1(): ret = [] for i in range(100): ret.append(‘包子%s‘%i) return ret baozi_list = product_baozi1() print(baozi_list) 第二種方法 def product_baozi2(): for i in range(100):print(‘正在生成包子‘) #要一次用一次,有一個值就可以馬上處理 yield ‘一屜包子%s‘%i print(‘開始買包子‘) pro_g = product_baozi2() baozi_1 = pro_g.__next__() print(baozi_1) baozi_2 = pro_g.__next__() print(baozi_2) baozi_3= pro_g.__next__() print(baozi_3) 結果 [‘包子0‘, ‘包子1‘, ‘包子2‘, ‘包子3‘, ‘包子4‘, ‘包子5‘, ‘包子6‘, ‘包子7‘, ‘包子8‘, ‘包子9‘, ‘包子10‘, ‘包子11‘, ‘包子12‘, ‘包子13‘, ‘包子14‘, ‘包子15‘, ‘包子16‘, ‘包子17‘, ‘包子18‘, ‘包子19‘, ‘包子20‘, ‘包子21‘, ‘包子22‘, ‘包子23‘, ‘包子24‘, ‘包子25‘, ‘包子26‘, ‘包子27‘, ‘包子28‘, ‘包子29‘, ‘包子30‘, ‘包子31‘, ‘包子32‘, ‘包子33‘, ‘包子34‘, ‘包子35‘, ‘包子36‘, ‘包子37‘, ‘包子38‘, ‘包子39‘, ‘包子40‘, ‘包子41‘, ‘包子42‘, ‘包子43‘, ‘包子44‘, ‘包子45‘, ‘包子46‘, ‘包子47‘, ‘包子48‘, ‘包子49‘, ‘包子50‘, ‘包子51‘, ‘包子52‘, ‘包子53‘, ‘包子54‘, ‘包子55‘, ‘包子56‘, ‘包子57‘, ‘包子58‘, ‘包子59‘, ‘包子60‘, ‘包子61‘, ‘包子62‘, ‘包子63‘, ‘包子64‘, ‘包子65‘, ‘包子66‘, ‘包子67‘, ‘包子68‘, ‘包子69‘, ‘包子70‘, ‘包子71‘, ‘包子72‘, ‘包子73‘, ‘包子74‘, ‘包子75‘, ‘包子76‘, ‘包子77‘, ‘包子78‘, ‘包子79‘, ‘包子80‘, ‘包子81‘, ‘包子82‘, ‘包子83‘, ‘包子84‘, ‘包子85‘, ‘包子86‘, ‘包子87‘, ‘包子88‘, ‘包子89‘, ‘包子90‘, ‘包子91‘, ‘包子92‘, ‘包子93‘, ‘包子94‘, ‘包子95‘, ‘包子96‘, ‘包子97‘, ‘包子98‘, ‘包子99‘] 正在生成包子 一屜包子0 開始買包子 正在生成包子 一屜包子1 開始買包子 正在生成包子 一屜包子2
母雞下蛋傳說
#母雞下蛋傳說 第一種方法 def xiadan(): ret = [] for i in range(100): ret.append(‘雞蛋%s‘%i) return ret print(xiadan()) #缺點是占用空間大(內存)和效率低 第二種 def xiadan1(): for i in range(100): yield ‘雞蛋%s‘%i laomuji = xiadan1() jidan = laomuji.__next__() print(‘海綿寶寶取了‘,jidan) jidan = laomuji.__next__() print(‘海綿寶寶取了‘,jidan) jidan = laomuji.__next__() print(‘海綿寶寶取了‘,jidan) 結果
第一種 [‘雞蛋0‘, ‘雞蛋1‘, ‘雞蛋2‘, ‘雞蛋3‘, ‘雞蛋4‘, ‘雞蛋5‘, ‘雞蛋6‘, ‘雞蛋7‘, ‘雞蛋8‘, ‘雞蛋9‘, ‘雞蛋10‘, ‘雞蛋11‘, ‘雞蛋12‘, ‘雞蛋13‘, ‘雞蛋14‘, ‘雞蛋15‘, ‘雞蛋16‘, ‘雞蛋17‘, ‘雞蛋18‘, ‘雞蛋19‘, ‘雞蛋20‘, ‘雞蛋21‘, ‘雞蛋22‘, ‘雞蛋23‘, ‘雞蛋24‘, ‘雞蛋25‘, ‘雞蛋26‘, ‘雞蛋27‘, ‘雞蛋28‘, ‘雞蛋29‘, ‘雞蛋30‘, ‘雞蛋31‘, ‘雞蛋32‘, ‘雞蛋33‘, ‘雞蛋34‘, ‘雞蛋35‘, ‘雞蛋36‘, ‘雞蛋37‘, ‘雞蛋38‘, ‘雞蛋39‘, ‘雞蛋40‘, ‘雞蛋41‘, ‘雞蛋42‘, ‘雞蛋43‘, ‘雞蛋44‘, ‘雞蛋45‘, ‘雞蛋46‘, ‘雞蛋47‘, ‘雞蛋48‘, ‘雞蛋49‘, ‘雞蛋50‘, ‘雞蛋51‘, ‘雞蛋52‘, ‘雞蛋53‘, ‘雞蛋54‘, ‘雞蛋55‘, ‘雞蛋56‘, ‘雞蛋57‘, ‘雞蛋58‘, ‘雞蛋59‘, ‘雞蛋60‘, ‘雞蛋61‘, ‘雞蛋62‘, ‘雞蛋63‘, ‘雞蛋64‘, ‘雞蛋65‘, ‘雞蛋66‘, ‘雞蛋67‘, ‘雞蛋68‘, ‘雞蛋69‘, ‘雞蛋70‘, ‘雞蛋71‘, ‘雞蛋72‘, ‘雞蛋73‘, ‘雞蛋74‘, ‘雞蛋75‘, ‘雞蛋76‘, ‘雞蛋77‘, ‘雞蛋78‘, ‘雞蛋79‘, ‘雞蛋80‘, ‘雞蛋81‘, ‘雞蛋82‘, ‘雞蛋83‘, ‘雞蛋84‘, ‘雞蛋85‘, ‘雞蛋86‘, ‘雞蛋87‘, ‘雞蛋88‘, ‘雞蛋89‘, ‘雞蛋90‘, ‘雞蛋91‘, ‘雞蛋92‘, ‘雞蛋93‘, ‘雞蛋94‘, ‘雞蛋95‘, ‘雞蛋96‘, ‘雞蛋97‘, ‘雞蛋98‘, ‘雞蛋99‘] 第二種 海綿寶寶取了 雞蛋0 海綿寶寶取了 雞蛋1 海綿寶寶取了 雞蛋2
生成器總結:
函數用return
生成器用yield,可以保留狀態
優點1.延遲計算,要的時候給你,也就是說,他不會一次性的生成所有的結果。這對於大數據處理,將會非常有用
列表解析
sum( [ i for i in range(10000000) ] ) 內存占用大,機器容易卡死
生成器表達式
sum( i for i in range(10000000)) 幾乎不占內存
優點2.生成器有效提高代碼可讀性
人口普查
人口普查.txt {‘name‘:‘北京‘,‘population‘:10100} {‘name‘:‘南京‘,‘population‘:10200} {‘name‘:‘東京‘,‘population‘:10300}
def get_population():
with open(‘人口普查.txt‘, ‘r‘, encoding=‘utf-8‘) as f:
for i in f:
yield i
g1=get_population()
g=get_population() #將生成器賦值給g
# s1 = eval(g.__next__()) #用eval將字符結構提取出來進行運算,因為從文章截取為字符串類型
# print(s1[‘population‘]) #取人口數量
# print(g.__next__())
#總人口
# res = 0
# for p in g:
# p_dic = eval(p)
# print(p_dic[‘population‘])
# res += p_dic[‘population‘]
# print(res)
#總人口(另一種)
for p in g:
all_popu = sum(eval(p)[‘population‘]for p in g)
print(int(all_popu))
for i in g1:
print(int(eval(i)[‘population‘])/all_popu)
註意事項:將生成器賦值給g,如果前面叠代完了,後面g就不能再用,只能叠代一次
還有的是文件名稱要寫完全,和編碼,什麽編碼寫的就用什麽編碼解。
int和str不可以進行相除
生產者消費者模型
並發運行 就是同時運行——利用yield, 因為yield可以保留狀態
python是順序運行
補充
1.yield相當於return控制的是函數的返回值
2.x=yield 的另外一個特性,接收send傳過來的值,賦值給x
def test(): print(‘開始了‘) firt = yield 1 #默認firt=None print(‘第一次‘,firt) yield 2 print(‘第二次‘) t = test() #這樣沒有運行 res = t.__next__() #這樣才算執行 print(res) #生成器運行的方法有三種 1.t.__next__() 2.next(t) 3.t.send(None) 其中send有兩個功能,一是可以觸發生成器運行,接著運行。二是函數停留再firt那個位置,我就是給firt賦值的
單人的消費者模式
單線程並發,來回的切換
def consumer(name): print(‘我是[%s],我準備開始吃包子了‘%name) while True: baozi = yield print(‘%s很高興把[%s]吃掉了‘%(name,baozi)) def producer(): c1 = consumer(‘wwe‘) c1.__next__() for i in range(10): c1.send(‘包子%s‘%i) producer()
隨堂筆記 19 day