python強(qiáng)大的引進(jìn)-生成器。這就是我們今天要學(xué)習(xí)的這一章內(nèi)容。 定義: 在Python中,這種一邊循環(huán)一邊計(jì)算的機(jī)制,稱為生成器(Generator)。換句更簡(jiǎn)單的話來(lái)理解:任何包含yield語(yǔ)句的函數(shù)稱為為生成器。 好處: 通過(guò)列表生成式,我們可以直接創(chuàng)建一個(gè)列表。但是,受到內(nèi)存限制,列表容量肯定是有限的。而且,創(chuàng)建一個(gè)包含100萬(wàn)個(gè)元素的列表,不僅占用很大的存儲(chǔ)空間,如果我們僅僅需要訪問(wèn)前面幾個(gè)元素,那后面絕大多數(shù)元素占用的空間都白白浪費(fèi)了。 所以,如果列表元素可以按照某種算法推算出來(lái),那我們是否可以在循環(huán)的過(guò)程中不斷推算出后續(xù)的元素呢?這樣就不必創(chuàng)建完整的list,從而節(jié)省大量的空間。 工作原理: 它是在for循環(huán)的過(guò)程中不斷計(jì)算出下一個(gè)元素,并在適當(dāng)?shù)臈l件結(jié)束for循環(huán)。對(duì)于函數(shù)改成的generator來(lái)說(shuō),遇到return語(yǔ)句或者執(zhí)行到函數(shù)體最后一行語(yǔ)句,就是結(jié)束generator的指令,for循環(huán)隨之結(jié)束。 如何創(chuàng)建: 1. 只要把一個(gè)列表生成式的【】換成()就可以。 2. 上圖的例子是用yield來(lái)說(shuō)明一下怎么創(chuàng)建生成器。 ![]() 打開(kāi)百度App,看更多圖片 其實(shí)與創(chuàng)建函數(shù)類似: 區(qū)別是,創(chuàng)建函數(shù)是return返回值。創(chuàng)建生長(zhǎng)期是yield產(chǎn)生多個(gè)值,每次產(chǎn)生一個(gè),函數(shù)就會(huì)凍結(jié),等在那里等待被再次激活。等激活后從停止的那點(diǎn)開(kāi)始執(zhí)行。 生成器種類: A. 循環(huán)生成器。與列表推導(dǎo)式類似。只不過(guò)一個(gè)是返回列表一個(gè)是返回生成器(不會(huì)立刻循環(huán))。請(qǐng)看下面例子來(lái)說(shuō)明區(qū)別。 >>> L = [x * x for x in range(10)] >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> g = (x * x for x in range(10)) >>> g at 0x104feab40> >>> for n in g: print n B. 遞歸生成器。 ![]() C. 通用生成器: 生成器的組成 1. 生成器函數(shù): def定義,包含yield部分。 2. 生成器迭代器:這個(gè)函數(shù)的返回部分。 生成器方法 send 類似于next,在比不過(guò)需要一個(gè)發(fā)送的參數(shù)。 def repeater(value): while True: new=(yield value) if new is not None:value=new >>> r=repeater(42) >>> r.next() 42 >>> r.send('hello world') 'hello world' throw方法: 使用異常類型調(diào)用,還有可選的值以及回溯對(duì)象,用于生成器內(nèi)引發(fā)一個(gè)異常。(在yield表達(dá)式中) close方法: 調(diào)用時(shí)不要參數(shù),用于停止生成器。 模擬生成器 當(dāng)舊版本不能使用時(shí)生成器時(shí),需要普通函數(shù)模擬生成器。 方式:1. result=[]防御函數(shù)體開(kāi)始處。 2. yield some_expression 用result.append(some_expression)代替。 3.函數(shù)末尾添加return result 注:前面的遞歸生成器flatten就可以用普通函數(shù)重寫(xiě)模擬生成器。 案例總結(jié) ![]() |
|