生成器与推导式
?一,生成器
生成器本質(zhì)就是迭代器
在python中有三種方式來獲取生成器
1.通過生成器函數(shù)
2.通過各種推到式來實現(xiàn)生成器
3.通過數(shù)據(jù)的轉(zhuǎn)換也可以獲取生成器
def func():print(11)return 22ret = func() print(ret)# 運行結(jié)果: 11 22?將函數(shù)中的return換成yield就是生成器
#函數(shù) def func():print('這是函數(shù)func')return '函數(shù)func' func()# 生成器 def func1():print('這是函數(shù)func1')yield '函數(shù)func' func1() yield def func():print(1)# return 5yield 5 print(func().__next__()) # 這樣生成一個生成器 print(func().__next__()) # 這樣生成一個生成器 print(func().__next__()) # 這樣生成一個生成器 print(func().__next__()) # 這樣生成一個生成器?
def func(): print(1) yield 2 print(3) yield 4 g=func() print(g.__next__()) print(g.__next__()) # 1 # 2 # 3 # 4 print(g.__next__()) #報錯 StopIteration?
# def func(): # print(1) # yield 2 # # print(3) # # yield 4 # print(func().__next__()) # print(func().__next__()) # print(func().__next__()) # 1 只是形成了一個生成器,一直在重復(fù) # 2 # 1 # 2 # 1 # 2?
python2? next() iter()
python3? next() __next__() iter()? __iter__()
?
碰到return就結(jié)束函數(shù)
碰到y(tǒng)ield不結(jié)束就掛起
生成器的好處,非常節(jié)省內(nèi)存
senddef func():print(1)a = yield 2 # 1.掛起 2.返回值 3.接受值print(a) # '123'print(3)b = yield 4print(b) #'234' g = func()print(g.__next__()) #1 2 g.send(None) print(g.send('123')) # send = next+傳值 # print(g.send('234')) # send = next+傳值# 1 # 2 # 123 # 3 # 4 def func():print(1)a = yield 2 # 1.掛起 2.返回值 3.接受值print(a) # '123'print(3)b = yield 4print(b) #'234'c = yield 9g = func()print(g.__next__()) #1 2 g.send(None) print(g.send('123')) # send = next+傳值 print(g.send('234')) # send = next+傳值 #多了一次迭代,應(yīng)該再加一個yield
?
第一次調(diào)用生成器的時候使用send里邊的值必須是None
yield from
def func():lst = ['衛(wèi)龍','老冰棍','北冰洋','牛羊配']yield from lst g = func() for i in g:print(i) def func():li = [1,2,3,4]# yield liyield from liret = func() # 把生成器的地址給了ret print(ret.__next__()) #1 # # 執(zhí)行ret這個變量的指向的生成器地址 print(ret) #<generator object func at 0x000001B3B3EA97D8> # # 在全局空間找到一個變量叫做ret的,打印它的值 值就是生成器的地址?
def func():li = [1,2,3,4]l2 = [5,6,7,8]yield from liyield from l2 ret = func() # 把生成器的地址給了ret print(ret.__next__()) print(ret.__next__()) print(ret.__next__()) print(ret.__next__()) print(ret.__next__()) def func():li = [1,2,3,4]l2 = [5,6,7,8]# yield from li# yield from l2for i in li:yield ifor em in l2:yield em # ret = func() # 把生成器的地址給了ret print(ret.__next__()) print(ret.__next__()) print(ret.__next__()) print(ret.__next__()) print(ret.__next__())?
總結(jié)
1.生成器的本質(zhì)就是一個迭代器
2.生成器一定是一個迭代器,迭代器不一定是一個生成器
3.生成器是可以讓程序員自己定義的一個迭代器
4.生成器的好處,節(jié)省內(nèi)存空間
5.生成器的特性 一次性的,惰性機制,從上向下
6.send相當(dāng)于 next+傳值,第一次觸生成器的時候,如果使用send(None)
?值必須是None,一般我建議你們使用__next__
7. python2 iter()? next()
python3 iter()? next()? __next__() __iter__()
8.yield from 將可迭代對象元素逐個返回
?二,推導(dǎo)式
1.列表推導(dǎo)式
li = [] for i in range(10):li.append(i) print(li) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print([i for i in range(10)]) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]?
li = [] for i in range(10):if i%2 == 1:li.append(i) print(li) #[1, 3, 5, 7, 9] print([i for i in range(10) if i%2 == 0]) # 過濾(篩選) #[0, 2, 4, 6, 8] #for 循環(huán)的嵌套 li = [] for i in range(10):for em in range(3):li.append(em) print(li) #[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2] print([j for i in range(10) for em in range(3) for j in range(5)])?
2.集合推導(dǎo)式
s = {i for i in range(10)} print(s) #{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}?
3.字典推導(dǎo)式
print({i:i+1 for i in range(10)}) #{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}?
4.沒有元組推導(dǎo)式? ? 其實是一個生成器推導(dǎo)式
g = (i for i in range(10)) print(g) #<generator object <genexpr> at 0x000001D7DD1497D8>?
?
?總結(jié)
1.外部需要容器包一下,? 里邊第一個位置 結(jié)果 剩下位置都是語句
2.推導(dǎo)式 -- 面試? 實現(xiàn)小的需求時可以使用推導(dǎo)式,推導(dǎo)式節(jié)省代碼
3.推導(dǎo)式不要寫太長,可讀性查.
轉(zhuǎn)載于:https://www.cnblogs.com/Xiao_Xu/p/10542785.html
總結(jié)
- 上一篇: 第二个议题
- 下一篇: 给一个整数数组,找到两个数使得他们的和等