python中哪个函数能生成集合_神奇的python系列11:函数之生成器,列表推导式
1.生成器
生成器的本質(zhì)是迭代器。
在python中有三種方式來獲取生成器
1.通過生成器函數(shù)
2.通過各種推到式來實(shí)現(xiàn)生成器
3.通過數(shù)據(jù)的轉(zhuǎn)換也可以獲取生成器
#函數(shù)
deffunc():print('這是函數(shù)func')return '函數(shù)func'func()#生成器
deffunc1():print('這是函數(shù)func1')yield '函數(shù)func'func1()#結(jié)果:
def foo(): #yield 關(guān)鍵字
print(1)yield 4 #yield 返回值 記錄執(zhí)行到哪里 停止
print(2)yield 5g= foo() # #產(chǎn)生一個生成器
print(g.__next__()) #g.__next__ 觸發(fā)啟動這個生成器
print(g.__next__()) #g.__next__ 觸發(fā)啟動這個生成器
生成器定義: 函數(shù)體中存在yield就是生成器,函數(shù)+()就產(chǎn)生 生成器
1.生成器 只能向下執(zhí)行
2.正常函數(shù)中,函數(shù)+()調(diào)用在個函數(shù)
yield和return的效果是一樣的,但是還是有點(diǎn)區(qū)別:
yield是分段來執(zhí)行一個函數(shù)
return是直接停止這個函數(shù)
deffunc():print("111")yield 222
print("333")yield 444gener=func()
ret= gener.__next__()print(ret)
ret2= gener.__next__()print(ret2)
ret3= gener.__next__()#最后?個yield執(zhí)?完畢. 再次__next__()程序報(bào)錯
print(ret3)
結(jié)果:111
222
333
444
當(dāng)程序運(yùn)行完最后一個yield,那么后面繼續(xù)運(yùn)行__next__()程序會報(bào)錯。__next__ 和 yield 要一一對應(yīng), 最后的一個yield下邊能寫就是不運(yùn)行。
生成器是一個一個的,一直向下進(jìn)行,不能向上.__next__()到哪,指針就指到哪兒.下一次繼續(xù)就獲取指針指向的值。
生成器的好處:節(jié)省空間
#面試題
deffoo():deffunc():print(1)yield 4
returnfunc
f=foo()
g=f()print(g.__next__())
send方法
send和__next__()一樣都可以讓生成器執(zhí)行到下一個yield
defeat():for i in range(1,10000):
a= yield '包子'+str(i)print('a is',a)
b= yield '窩窩頭'
print('b is', b)
e=eat()print(e.__next__())print(e.send('大蔥'))print(e.send('大蒜'))
send和__next__()區(qū)別:
1.send 和 next()都是讓生成器向下走一次。
2.send可以給上一個yield的位置傳遞值,不能給最后一個yield發(fā)送值,在第一次執(zhí)行生成器的時候不能使用send()
3.第一次調(diào)用的時候使用send()也可以但是send的參數(shù)必須是None
生成器可以for循環(huán)來循環(huán)獲取內(nèi)部元素:
deffunc():yield 1
yield 2
yield 3
yield 4
yield 5f=func()for i inf:print(i)
yield from
在python3中提供一種可以直接把可迭代對象中的每一個數(shù)據(jù)作為生成器的結(jié)果進(jìn)行返回
deffunc():
lst= ['衛(wèi)龍','老冰棍','北冰洋','牛羊配']yield fromlst
g=func()for i ing:print(i)
deffunc():
lst= ['衛(wèi)龍','勞賓光','北冰洋']
lst2= ['aa','老冰棍','北冰洋123']yield fromlstyield fromlst2
g=func()for i ing:print(i)#注意:yield from 是將列表中的每一個元素返回,所以 如果寫兩個yield #from 并不會產(chǎn)生交替的效果
2.推導(dǎo)式
列表推導(dǎo)式
列表推導(dǎo)式的常?寫法:
[結(jié)果?for?變量?in?可迭代對象]
ls = [i for i in range(10)]print(ls)
篩選模式
[結(jié)果 for 變量 in 可迭代對象 if 條件]
li = [i for i in range(10) if i > 3]print(li)
字典推導(dǎo)式
lst1 = ['1','2']
lst2= [2,3]
d= {lst1[i]:lst2[i] for i in range(2)}print(d)
集合推導(dǎo)式
dic = {'1':2,'3':4}
d= {i for i indic.items()}print(d)
生成器推導(dǎo)式: 長得像元組的推導(dǎo)式 其實(shí)是生成器推導(dǎo)式 #沒有元組推導(dǎo)式
li = (i for i in range(100) if i>3)for i in range(10):print(li.__next__())
生成器表達(dá)式和列表推導(dǎo)式的區(qū)別:
1. 列表推導(dǎo)式比較耗內(nèi)存,一次性加載.生成器表達(dá)式幾乎不占用內(nèi)存.使用的時候才分配和使用內(nèi)存
2. 得到的值不一樣,列表推導(dǎo)式得到的是一個列表.生成器表達(dá)式獲取的是一個生成器
生成器的惰性機(jī)制: 生成器只有在訪問的時候才取值,說白了.你找他要才給你值.不找他要.他是不會執(zhí)行的.
deffunc():print(111)yield 222g= func() #生成器g
g1= (i for i in g) #生成器g1. 但是g1的數(shù)據(jù)來源于g
g2= (i for i in g1) #生成器g2. 來源g1
print(list(g)) #獲取g中的數(shù)據(jù). 這時func()才會被執(zhí)行. 打印111.獲取到222. g完畢.
print(list(g1)) #獲取g1中的數(shù)據(jù). g1的數(shù)據(jù)來源是g. 但是g已經(jīng)取完了. g1 也就沒有數(shù)據(jù)了
print(list(g2)) #和g1同理理
print(next(g))print(next(g1))print(next(g2)) #可以用next來驗(yàn)證 其實(shí)list就是將內(nèi)容迭代了轉(zhuǎn)換成了列表
注意:生成器是要值的時候才能拿值
總結(jié):
1.推導(dǎo)式有, 列表推導(dǎo)式, 字典推導(dǎo)式, 集合推導(dǎo)式,?沒有元組推導(dǎo)式
2.生成器表達(dá)式: (結(jié)果 for 變量量 in 可迭代對象 if 條件篩選)
3.生成器表達(dá)式可以直接獲取到?成器對象. ?成器對象可以直接進(jìn)行for循環(huán). ?成器具有惰性機(jī)制.
3.面試題
defadd(a, b):return a +bdeftest():for r_i in range(4): #[0,1,2,3]
yieldr_i
g=test()for n in [5,10]:
g= (add(n, i) for i ing)print(list(g))#拆解:#n = 2#g1 = (add(n,i) for i in g) #[10,11,12,13]#n = 10#g2 = (add(n,i) for i in g1) #[20,21,22,23]#print(list(g2))#結(jié)果 [20,21,22,23]
總結(jié)
以上是生活随笔為你收集整理的python中哪个函数能生成集合_神奇的python系列11:函数之生成器,列表推导式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wpf 动画_WPF中监视动画进度
- 下一篇: python3.7界面设计_基于sele