python基础之生成器,生成器函数,列表推导式
生活随笔
收集整理的這篇文章主要介紹了
python基础之生成器,生成器函数,列表推导式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
內容梗概:
1. 生成器和生成器函數.
2. 列表推導式.
1.生成器函數
1.1 生成器函數. 就是把return換成yield
def gen():print("爽歪歪")yield "娃哈哈" # 可以讓我們的函數分段運行print("酸酸乳")yield "AD鈣奶"print("黃燜雞米飯")ret = gen() # 不會執行你的函數, 獲取到生成器對象
# 迭代器不能等價代換
print(ret) # <generator object gen at 0x00000195518CFE60> generator 生成器
print(ret.__next__()) # 必須執行__next__()才可以觸發生成器的運行 娃哈哈
print(ret.__next__()) # 必須執行__next__()才可以觸發生成器的運行 AD鈣奶
print(ret.__next__()) # StopIteration 迭代器, 就找yield, 執行不到才會報錯 1.2 生成器函數的作用:節省內存,要多少用多少 def gen():lst = []for i in range(1, 10000):lst.append("衣服%s" % i)if i % 50 == 0: # 1 2 3 4 5 6 7 8 9 .. 49 50yield lstlst = [] # 每次生成一個新列表g = gen() # 獲取到生成器print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
生成器和迭代器有相同的特點
# 節省內存
# 惰性機制
# 只能往前
生成器還可以使用__next__(), send()來訪問生成器
send()可以給上一個yield位置傳值
詳見實例:
def func():print("水餃")a = yield "大餡水餃"print("a=", a)print("燒餅")b = yield "武大郎燒餅"print("b=",b)print("老婆餅")c = yield "只要老婆不要餅"print("c=", c)
1.3 x.send()的用法
gen = func() # 生成器
print("返回值是:", gen.__next__())
print("返回值是:",gen.send("混沌面")) # 和__next__()一樣也是向下找yield. 給上一個yield傳值
print("返回值是:",gen.send("胡辣湯")) # 和__next__()一樣也是向下找yield. 給上一個yield傳值
print("返回值是:",gen.send("馬拉")) # 和__next__()一樣也是向下找yield. 給上一個yield傳值 send()不可以在第一個位置和最后一個位置出現
最后的yield后的代碼是可以執行的但是會報錯. StopIteration
注意:
生成器函數里不要寫return
def func():print("哈哈")yield "呵呵"print("吼吼")return "嘻嘻" # don't do this! gen = func()gen.__next__()gen.__next__()
2.推導式
2.1列表推導式:
lis = [結果 for循環 if判斷語句]
實例1 篩選出名字長度小于二的
lst = ["中島美雪", "夏川美里", "原由子", "汪峰", "田震","那英","周杰倫"]
new_lst = [ el for el in lst if len(el) == 2] #此處快速創建了一個新列表,并用IF語句做出來篩選
print(new_lst)
實例2 [3,6,9] 已知 求轉換成[(1,2,3), (4,5,6), (7,8,9)]lst = [3,6,9]
new_lst = [(el-2, el-1, el) for el in lst]
2.2 字典推導式 {結果 for循環 if判斷}
實例一 lst = [11, 22, 33] # => {0:11, 1:22, 2:33} dic = {i:lst[i] for i in range(len(lst)) } #字典推導式 print(dic) 實例二 dic = {"張無忌":"趙敏", "楊過":"小龍女", "郭靖":"黃蓉"} # 把字典中的key和value互換 # dic = {"趙敏":"張無忌", "小龍女":"楊過", "黃蓉":"郭靖"} 法1 dic1 = { v:k for k, v in dic.items()} # 強化 print(dic1) 法2 dic2 = { dic[k]:k for k in dic} # 強化 print(dic2)
2.3 集合推導式 # 特點: 不可變. 不重復, 無序
{結果 for循環 if判斷}
s = {i*"胡辣湯" for i in range(10)}
print(s)
注意: 沒有元組推導式
2.1 生成器表達式 (結果 for循環 if判斷) => 生成器表達式
2.1.1特點: 本質是迭代器. __next__()
1. 省內存
2. 惰性機制
3. 只能向前
2.1.2為啥省內存?
lst = ["衣服%s" % i for i in range(100000000)] # 占內存 print(lst)g = ("衣服%s" % i for i in range(100000000)) # 生成器表達式. 節省內存,要多少多少 print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__())
生成器推導式的一些坑
1. list()里面包含循壞,會循環生成器,打印成列表
2.生成器的惰性機制,拿一次取一次
詳見實例:
實例1:
g = (i for i in range(10)) print(list(g)) # 把傳遞進來的數據轉化成列表. 里面包含了for循環 list() => for=> __iter__() ==> __next__() print(list(g)) # 上一次已經拿沒了,因為生成器是一次性的,且只能往前取值,所以會打印出空表格 print(g.__next__()) for el in g:print(el) for el in g: # 已經沒有數據了 惰性機制-> 只能往前print(el)
實例2 :
def func(): # 生成器函數print(111)yield 222 g = func() # 生成器 -> 沒有執行過__next__() g1 = (i for i in g) # 生成器表達式. 也沒有__Next__() g2 = (i for i in g1) # 生成器表達式. 也沒有__Next__() # 到此為止, 沒有人拿過值 print(list(g)) # 111 [222] print(list(g1)) # [] #因為前面的g已將拿過值了,g已經空了,先到先得 print(list(g2)) # []
tips:生成器表達式和列列表推導式的區別:
1. 列表推導式比較耗內存. 一次性加載. 生成器表達式幾乎不占?用內存. 使用的時候才分配和使用內存
2. 得到的值不一樣. 列表推導式得到的是?個列列表. 生成器表達式獲取的是?個生成器.
補充知識點:yield from
在python3中提供了了一種可以直接把可迭代對象中的每一個數據作為生成器的結果進行返回
def gen():lst1 = ["?花藤", "胡辣湯", "微星牌餅鐺", "Mac牌鍋鏟"]lst2 = ["餅鐺還是微星的好", "聯想不能煮雞蛋", "微星就可以", "還可以烙餅"]yield from lst1yield from lst2 g = gen() for el in g:print(el) #結果會先將lst1先打印完,然后再打印lst2
?
轉載于:https://www.cnblogs.com/Mixtea/p/9892265.html
總結
以上是生活随笔為你收集整理的python基础之生成器,生成器函数,列表推导式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求这是什么电影,里面互换卷子
- 下一篇: 洱海是坐船玩好还是坐吉普车好