1、上節回顧:python
一、可迭代對象:惰性運算 擁有__iter__方法面試
二、迭代器: 擁有__iter__和__next__方法app
三、生成器:惰性運算,開發者自定義 本質:迭代器 因此擁有__iter__和__next__方法ide
惰性運算:不取值就不計算 且每個值只能被取一次,取完爲止函數
生成器的優勢:延遲計算,一次返回一個結果,也就是說,它不會一次生成全部的結果,這對於大數據處理很是有用大數據
生成器------迭代器:節省內存spa
1)生成器函數:3d
帶有yield 關鍵字code
執行函數以後的返回值是生成器,函數內的代碼並不會真正執行對象
想讓生成器吐出數據,須要使用next 方法,send, for循環
2、新內容
一、生成器的調用例子 取用:cloth
def cloth(): for i in range(100): yield "衣服%s"%i g=cloth() # 方法一 # for i in g: # print(i) # 方法二 for i in range(100): print(g.__next__())
二、監聽文件末尾追加的例子
調用生成器並不執行,當取用的時候纔會執行def下面的內容(Windows系統的時候纔可使用)
def tail(): f=open("你好.bak","r",encoding="utf-8") f.seek(0,2) while True: line=f.readline() if line: yield line import time time.sleep(0.1) g=tail() for i in g: print(i.strip())
三、send 和next 的範圍是同樣的
(1)從哪個yield開始接着執行,就把一個值傳給了那個yield
(2)send 不能用在第一個觸發生成器,觸發生成器第一個必須是__next__()
(3)生成器函數中有多少個yield就必須有多少個next+send
def func(): print("*"*10) a=yield 5 print(a) yield 10 g=func() num=g.__next__() print(num) num2=g.send("alex") print(num2) # ********** # 5 # alex # 10
def averager(): total=0.0 count=0 average=None while True: term=yield average total+=term count+=1 average=total/count g_avg=averager() g_avg.__next__() print(g_avg.send(10)) print(g_avg.send(20)) print(g_avg.send(30)) # 10.0 # 15.0 # 20.0
四、補充:python3 以後有的這個功能:yield from a
def func(): a="AB" b="CD" yield from a #for i in a:yield i yield from b #for i in b:yield i g_func=func() for i in g_func: print(i)
五、觸發執行的方式
(1)生成器.__next__()
(2)生成器.send()
send(None)==__next__().
send在next的基礎上傳一個值到生成器函數的內部
send 操做不能用在生成器使用的第一次
以上兩個執行幾回拿幾個數據,可能會遇到取完報錯
(3)for循環 每次取一個,取完爲止。for循環不會報錯
六、總結:
生成器函數:生成一個生成器的函數
生成器的本質:參數迭代器
生成器函數的特色:(1)帶有yield 關鍵字 (2)且調用以後,函數內的代碼不執行
觸發執行的方式:(1)next (2)send (3)for 循環
3、各類推導式
一、列表推導式:
y=[1,2,3,4,5,6,7] # 方法一 # x=[] # for i in y: # x.append(i**2) # print(x) # 方法二 x=[i**2 for i in y] print(x) # [1, 4, 9, 16, 25, 36, 49]
# x=[] # for i in range(100): # x.append(i/2) # print(x) x=[i/2 for i in range(100)] print(x)
二、生成器表達式 (生成器表達式+for循環節省內存 推薦使用)
#列表推導式 y=[1,2,3,4,5,6] x=[i**2 for i in y] #[ ] print(x) #生成器表達式 y=[1,2,3,4,5,6] g=(i**2 for i in y) #( ) print(g) for i in g: print(i)
l=["雞蛋%s"%i for i in range(10)] print(l) lmuji=("雞蛋%s"%i for i in range(10)) for egg in lmuji : print(egg)
三、補充:
並非全部的均可以轉換
g.__next__()==next(g ) g.__iter__()==inter(g)
四、30之內能被3整除的數的平方 列表推導式的例子
# 30之內能被3整除的數的平方 # x=[i**2 for i in range(30) if i%3==0] # print(x) def square(x): return x**2 x=[square(i) for i in range(30) if i%3==0] print(x)
五、字典推導式
dic={"a":10,"b":34} dic_fre={dic[k]:k for k in dic} print(dic_fre) #{10: 'a', 34: 'b'} key value 對換
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} print(mcase_frequency) #{'a': 17, 'b': 34, 'z': 3}
六、集合的推導式 去重
squared={x**2 for x in [1,-1,2]} print(squared) #set([1,4])
面試題: