<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
通過列表⽣成式,我們可以直接建立⼀個列表。
但是,受到記憶體限制,列表容量肯定是有限的。
⽽且,建立⼀個包含100萬個元素的列表,不僅佔⽤很⼤的儲存空間,如果我們僅僅需要存取前⾯⼏個元素,那後⾯絕⼤多數元素佔⽤的空間都⽩⽩浪費了。
所以,如果列表元素可以按照某種演演算法推算出來,那我們是否可以在迴圈的過程中不斷推算出後續的元素呢?
# 列表生成式 lst = [i for i in range(10)] print(lst) print(type(lst)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # <class 'list'>
g = (i for i in range(10)) print(g) print(type(g)) # <generator object <genexpr> at 0x00000190CC886350> g是一個生成器物件 # <class 'generator'> g的型別是生成器
這樣就不必建立完整的list,從⽽節省⼤量的空間。在Python中,這種⼀邊迴圈⼀邊計算的機制,稱為⽣成器:generator。
建立 列表 和 生成器 的區別僅在於最外層的 [ ] 和 ( ) , lst 是⼀個列表,⽽ g 是⼀個⽣成器。我們可以直接列印出 lst 的每⼀個元素,但我們怎麼列印出 g 的每⼀個元素呢?如果要⼀個⼀個列印出來,可以通過 next() 函數獲得⽣成器的下⼀個返回值:
print(next(g)) # 0 print(next(g)) # 1 print(next(g)) # 2 print(next(g)) # 3 print(next(g)) # 4 print(next(g)) # 5 print(next(g)) # 6 print(next(g)) # 7 print(next(g)) # 8 print(next(g)) # 9 print(next(g)) ''' Traceback (most recent call last): File "E:/Python Project/直播答疑/5.生成器.py", line 47, in <module> print(next(f)) StopIteration '''
也可以通過for-in迴圈列印出來
for i in g: print(i) ''' 0 1 2 3 4 5 6 7 8 9 '''
⽣成器儲存的是演演算法,每次調⽤ next(g) ,就計算出 g 的下⼀個元素的值,直到計算到最後⼀個元素,沒有更多的 元素時,丟擲 StopIteration 的異常。 當然,這種不斷調⽤ next() 實在是太繁瑣了,雖然是點一次出現一次,但正 確的⽅法是使⽤ for 迴圈,因為⽣成器也是可迭代物件。 所以,我們建立了⼀個⽣成器後,基本上永遠不會調⽤ next() ,⽽是通過 for 迴圈來迭代它,並且不需要關心StopIteration 異常。 所以,我們建立了一個生成器後,基本上不會呼叫 next() ,而是通過 for 迴圈來迭代它,並且不需要關心 StopIteration 的錯誤。generator非常強大。如果推算的演演算法比較複雜,用類似列表生成式的 for 迴圈無法實 現的時候,還可以用函數來實現。比如,著名的斐波拉契數列(Fibonacci),除第一個和第二個數外,任意一個 數都可由前兩個數相加得到: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 斐波拉契數列用列表生成式寫不出來,但是,用函數把它列印出來卻很容易: 程式碼如下
# 定義一個斐波那契函數 def fib(times): # 初始化 n = 0 a, b = 0, 1 while n < times: print(b) a, b = b, a+b n += 1 fib(6) ''' 1 1 2 3 5 8 '''
仔細觀察,可以看出,fifib_a函數實際上是定義了斐波拉契數列的推算規則,可以從第一個元素開始,推算出後續任意的元素,這種邏輯其實非常類似generator。 也就是說,上面的函數generator僅一步之遙。要把 fib 函數變 成generator,只需要把 print(b) 改為 yield(b) 就可以了:
def fib(times): # 初始化 n = 0 a, b = 0, 1 while n < times: yield b a, b = b, a+b n += 1 f = fib(6) print(f) # <generator object fib at 0x00000197C5E56350> # f 是一個生成器物件 print(next(f)) print(next(f)) print(next(f)) print(next(f)) print(next(f)) print(next(f)) ''' 1 1 2 3 5 8 ''' print(next(f)) ''' Traceback (most recent call last): File "E:/Python Project/直播答疑/5.生成器.py", line 47, in <module> print(next(f)) StopIteration '''
在上⾯fifib 的例⼦,我們在迴圈過程中不斷調⽤ yield ,就會不斷中斷。當然要給迴圈設定⼀個條件來退出迴圈,不然就會產⽣⼀個⽆限數列出來。同樣的,把函數改成generator後,我們基本上從來不會⽤ next() 來獲取下⼀個返 回值,⽽是直接使⽤ for 迴圈來迭代:
def fib(times): # 初始化 n = 0 a, b = 0, 1 while n < times: yield b a, b = b, a+b n += 1 f = fib(6) for i in f: print(i) ''' 1 1 2 3 5 8 '''
1.通過next()函數
2.通過迴圈列印 for- in
3.objict內建的__next__()方法
4.send() 方法,生成器的第一個值必須是send(None),後面沒有限制
# 建立一個生成器 g = (i for i in range(10)) print(next(g)) print(next(g)) # 0 # 1 print(g.__next__()) print(g.__next__()) # 2 # 3 print(g.send(None)) print(g.send('')) print(g.send(1)) # 4 # 5 # 6 for i in g: print(i) ''' 7 8 9 '''
⽣成器是這樣⼀個函數,它記住上⼀次返回時在函數體中的位置。對⽣成器函數的第⼆次(或第 n 次)調⽤跳轉⾄該函數中間,⽽上次調⽤的所有區域性變數都保持不變。 ⽣成器不僅“記住”了它資料狀態;⽣成器還“記住”了它在流 控制構造(在指令式程式設計中,這種構造不只是資料值)中的位置。 ⽣成器的特點:
'''
1. 節約記憶體
2. 迭代到下⼀次的調⽤時,所使⽤的引數都是第⼀次所保留下的,在整個所有函數調⽤的引數都是第⼀次所調⽤
時保 留的,⽽不是新建立的
'''
到此這篇關於Python淺析生成器generator的使用的文章就介紹到這了,更多相關Python生成器generator內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45