1,生成器
只要含有yield關鍵字的函數都是生成器函數
yield不能和return共用且須要寫在函數內
生成器函數的特色:
①調用函數以後函數不執行,返回該生成器
②每次調用__next__方法時會取到一個值
③直到取完最後一個,在執行__next__會報錯
def generator(): #生成器函數
print(2)
yield 'a'
ret = generator() #調用生成器函數,但並不會執行,而是返回一個生成器及地址
print(ret) #>>><generator object generator at 0x000002582D4596D8>
2,簡單生成器函數的使用
def generator():
print(2)
yield 'a' #yield與return在相同的位置,都會返回後面的值,
# 可是yield不會結束函數,return會結束函數
ret = generator()
g = ret.__next__()
print(g)
3,yield
yield做用暫停生成器函數但不結束,並將yield後面的返回到調用的地方(即便用了 「生成器.__next__()」 的地方),當再次使用 「生成器.__next__()」 時生成器函數就會從暫停位置繼續執行。
4,生成器的使用
從生成器中取值的幾個方法:
①__next__
②for循環
③數據類型的強制轉換,可是佔用內存大。如:把生成器轉爲列表 list(g)
def wa():
for i in range(100):
yield '娃哈哈%s'%i
g = wa()
for i in g:
print(i)
#只用其中的50個
g = wa()
count = 0
for i in g:
count += 1
print(i)
if count > 50:
break #for循環結束,生成器暫停並無結束
# 繼續索要接下來的值
print('**',g.__next__()) #隨時能夠索要接下來的值
5,監聽文件輸入的栗子:
#新輸入的文本保存後才能被讀取
def tail(filename):
f = open(filename,encoding='utf-8')
while True:
line = f.readline()
if line.strip():
yield line.strip()
g = tail('file')
for i in g:
print(i)
6,生成器中send()的使用
6.1,獲取移動平均值
def average():
sum = 0
count = 0
avg = 0
while True:
num = yield avg
sum += num
count += 1
avg = sum/count
avg_g = average() #調用函數以後函數不執行,返回應該生成器
avg_g.__next__() #使用生成器,暫停在yield #使用send()時,第一次使用生成器必須先使用__next__()方法激活一次。
avg1 = avg_g.send(10) #使用send()發後一個值返回到上次暫停的yield,並執行__next__()的功能一次,
avg1 = avg_g.send(20) #生成器中最後一個yield不能接受外部的值
print(avg1)
7,生成器的裝飾器
def init(func):
def inner(*args,**kwargs):
g = func(*args,**kwargs)
g.__next__()
return g
return inner
@init
def average():
sum = 0
count = 0
avg = 0
while True:
num = yield avg
sum += num
count += 1
avg = sum/count
avg_g = average()
ret = avg_g.send(10)
print(ret)
8,想將分開一個一個的輸出就用yield from
def generator():
a = 'abcde'
b ='12345'
yield from a
yield from b
g = generator()
for i in g:
print(i)
注意:yield from 是將yield from 後的遍歷完,而後在執行其它的代碼。
上例子中,先執行 yield from a 將a遍歷完,讓那後執行 yield from b 。
至關與下面的代碼:
def generator():
a = 'abcde'
b = '12345'
for i in a:
yield i
for i in b:
yield i
g = generator()
for i in g:
print(i)
9,表達式
9.1,列表推導式
print(['雞蛋%s'%i for i in range(10)])
結果:['雞蛋0', '雞蛋1', '雞蛋2', '雞蛋3', '雞蛋4', '雞蛋5', '雞蛋6', '雞蛋7', '雞蛋8', '雞蛋9']
至關於下面的代碼:
egg_list = []
for i in range(10):
egg_list.append('雞蛋%s'%i)
print(egg_list)
9.2,生成器表達式
g = (i for i in range(10))
print(g)
for i in g:
print(i)
9.3,列表推導式:
9.3.1,栗子1:30之內全部能被整除的數
ret = [i for i in range(30) if i % 3 == 0]
print(ret)
9.3.2,栗子2:30之內全部能被整除的數的平方
ret = [i*i for i in range(30) if i % 3 == 0]
print(ret)
9.3.3,栗子3;找到嵌套列表中名字含有兩個’e‘的全部名字
names = [['Tom','Billy','Jefferson','Steven'],['Jennifer','Eva']]
ret = [name for lst in names for name in lst if name.count('e') == 2]
print(ret)
names = [['Tom','Billy','Jefferson','Steven'],['Jennifer','Eva']] ret = [] for lst in names: for name in lst: if name.count('e') == 2: ret.append(name) print(ret)
9.4,字典推導式:
· 9.4.1,栗子1:將一個字典的key和value對調
mcase = {'a': 10, 'b': 34}
mcase_frequency = {mcase[k]: k for k in mcase}
print(mcase_frequency)
9.4.2,合併大小寫對應的value值,將k統一成小寫
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys()}
print(mcase_frequency)
9.5,集合推導式:
9.5.1,栗子1:計算列表中每一個值的平方,自帶去重功能
squared = {x**2 for x in [1, -1, 2]}
print(squared)
10,練習python
10.1,處理文件,用戶指定要查找的文件和內容,將文件中包含要查找內容的每一行都輸出到屏幕app
def check_file(filename,aim):
with open(filename, encoding='utf-8') as f:
for i in f:
if aim in i:
yield i
g = check_file('文件','內容')
for i in g:
print(i.strip())
10.2,寫生成器,將文件中讀取內容,在每一次讀取到的內容以前加上'***'以後再返回給用戶。ide
def check_file(filename):
with open(filename,encoding='utf-8) as f:
for i in f:
yield '***'+i
for i in check_file('文件'):
print(i.strip())
10.3函數
def demo():
for i in range(4):
yield i
g = demo() #g,g1,g2都是生成器
g1 = (i for i in g)
g2 = (i for i in g1)
print(list(g1)) #這個時候纔開始執行
print(list(g2)) #由於在執行上一句時,生成器g1,g都已經執行完了,
#因此g2就不會有值,一個生成器只能執行一次
#結果:
[0, 1, 2, 3]
[]
10.4,裝飾器推導式與for的嵌套spa
def add(n,i):
return n+i
def test():
for i in range(4):
yield i
g = test()
for n in [1,10]:
g = (add(n,i) for i in g) #這兩句等同於下面的內容
# n = 1
# g = (add(n,i) for i in g)
# n = 10
# g = (add(n,i) for i in (add(n,i) for i in test())) #此時 in g 的這個g是上一個賦值的東西
#到這爲止,都尚未真正的執行,只是產生生成器
print(list(g)) #到這纔開始真正的執行,且執行的結果就是上一句執行完的結果