久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

技術(shù)|Python從零開始系列連載(二十)——生成器

 藍(lán)天cipvfv9gyo 2018-06-10

還記得在迭代器里我們說(shuō)為什么將列表轉(zhuǎn)為迭代器么,?(傳送門

小明:因?yàn)榱斜硖蟮脑捳加脙?nèi)存太大,做成迭代器可以節(jié)省空間,,用的時(shí)候再拿出部分

是的,,今天要講的生成器是不會(huì)把結(jié)果保存在一個(gè)系列中,而是保存生成器的狀態(tài),。

在每次進(jìn)行迭代時(shí)返回一個(gè)值,,直到遇到StopIteration異常結(jié)束。

見過(guò)這種東西吧:

技術(shù)|Python從零開始系列連載(二十)——生成器

你可以認(rèn)為每一杯飲料就是一個(gè)生成的對(duì)象,,我不會(huì)一次倒出所有的飲料

而是要喝的時(shí)候去倒出一杯(也就是需要的時(shí)候生成一個(gè))

簡(jiǎn)單方法創(chuàng)建生成器

我們看個(gè)例子:

技術(shù)|Python從零開始系列連載(二十)——生成器

我們發(fā)現(xiàn),,當(dāng)要生成的list非常大時(shí),拋出異常,,存儲(chǔ)報(bào)錯(cuò),。

那怎樣生成這種巨大的list呢?

技術(shù)|Python從零開始系列連載(二十)——生成器

你親手試一下,,發(fā)現(xiàn)瞬間程序就運(yùn)行結(jié)束了

我們看到,,b是一個(gè)generator,也就是生成器模式

你應(yīng)該已經(jīng)注意到,,生成器的創(chuàng)建很簡(jiǎn)單,,將列表生成式的中括號(hào)改成小括號(hào)即可

注意:這里說(shuō)的不是列表,因?yàn)榱斜淼闹欣ㄌ?hào)改成小括號(hào)是元組,!

那我們?cè)趺瓷梢粋€(gè)內(nèi)容呢,?

和之前的迭代器相同,使用next()函數(shù)即可:

技術(shù)|Python從零開始系列連載(二十)——生成器

直到最后會(huì)拋出異常,,也就是到達(dá)了生成器的末端了

函數(shù)進(jìn)化為生成器

還記得函數(shù)的定義么,?

我們?cè)谥坝眠f歸定義了一個(gè)斐波那契數(shù)列

現(xiàn)在我們定義一個(gè)新的函數(shù)來(lái)生成斐波那契數(shù)列的第n項(xiàng)

技術(shù)|Python從零開始系列連載(二十)——生成器

為了實(shí)現(xiàn)后一項(xiàng)等于前兩項(xiàng)之和使用了a,b = b,,a+b

為什么這樣寫,,留給大家思考~

提示:可以輸入n=3,自己感受一下調(diào)用函數(shù)過(guò)程中a和b的變化

值得注意的是,,這個(gè)函數(shù),當(dāng)n=0時(shí)返回的是1,,而不是正確的0

所以我們對(duì)其進(jìn)行修改:

技術(shù)|Python從零開始系列連載(二十)——生成器

在循環(huán)之前,,加了一個(gè)判斷

小明:老濕!你這個(gè)說(shuō)的還是函數(shù)啊,,和生成器有啥關(guān)系,?說(shuō)好的函數(shù)進(jìn)化成生成器呢?

好的,,我們看看函數(shù)怎么進(jìn)化為生成器,!

技術(shù)|Python從零開始系列連載(二十)——生成器

我們把函數(shù)中的return換成yield

函數(shù)就進(jìn)化成了生成器,當(dāng)我們調(diào)用時(shí),發(fā)現(xiàn)返回的是生成器對(duì)象

為了拿到數(shù)據(jù),,我們應(yīng)該怎么做呢,?

小紅:老師,是不是可以試試next()函數(shù)呢,?

對(duì),,不過(guò)在此之前,我們先要用一個(gè)變量去接收這個(gè)生成器對(duì)象

并且為了觀察生成器的特點(diǎn),,我們對(duì)函數(shù)進(jìn)行修改,!

仔細(xì)看好:

技術(shù)|Python從零開始系列連載(二十)——生成器

當(dāng)我們使用next(a)對(duì)生成器操作一次時(shí),會(huì)返回循環(huán)一次的值

也就是在yield處結(jié)束本次運(yùn)行

但它的特點(diǎn)就是下次使用next(a)時(shí),,接著上次的斷點(diǎn)繼續(xù)運(yùn)行,,直到下一個(gè)yield

不斷使用next(a),直到運(yùn)行到生成器結(jié)尾處,,如下圖:

技術(shù)|Python從零開始系列連載(二十)——生成器

可能你對(duì)他的運(yùn)行過(guò)程還不是特別清晰

我們加上print輸出來(lái)徹底搞懂他的運(yùn)行過(guò)程:

技術(shù)|Python從零開始系列連載(二十)——生成器

發(fā)現(xiàn)每次返回值都是在yield的地方了吧~

小結(jié):

  1. 講了兩種生成器創(chuàng)建方式
  2. 加了yield的函數(shù)就變成了生成器
  3. 要定義一個(gè)變量接收生成器的返回值
  4. 使用next()獲取生成器每次返回的值,,并且斷點(diǎn)在yield處
  5. 下次使用next()從上次的斷電往下執(zhí)行,直到生成器末端(這里表現(xiàn)為循環(huán)結(jié)束)
  6. 生成器屬于迭代器,,所以肯定是可迭代對(duì)象啦~

使用for循環(huán)調(diào)用生成器

我們使用next()去遍歷生成器的時(shí)候,,我們不知道什么時(shí)候會(huì)結(jié)束

而結(jié)束后再使用next()會(huì)拋出異常

因?yàn)樯善鲗儆诘?/p>

所以我們可以使用for循環(huán)去調(diào)用生成器

技術(shù)|Python從零開始系列連載(二十)——生成器

與next()等價(jià)的方式

技術(shù)|Python從零開始系列連載(二十)——生成器

send()強(qiáng)勢(shì)入場(chǎng)

我們先看一個(gè)例子:

技術(shù)|Python從零開始系列連載(二十)——生成器

發(fā)現(xiàn)每次運(yùn)行,除了返回下一個(gè),,還會(huì)打印出None

觀察代碼,,注意 item = yield i 這句

首先執(zhí)行等號(hào)右邊的,yield返回,,此時(shí),,返回生成器一個(gè)對(duì)象,并且中斷

在下次使用 f.__next__( )時(shí)候,,并沒(méi)有傳內(nèi)容進(jìn)去,,所以可以認(rèn)為yield i 這整個(gè)賦值給item的為None

所以item打印出為None

為了做個(gè)比較,引入send()

技術(shù)|Python從零開始系列連載(二十)——生成器

send()可以看做next()的增強(qiáng)版

除了可以使用next()功能

還能傳入一個(gè)值到上次yield斷開地方的整體表達(dá)式(這里傳給是yield i)

send()的坑:

技術(shù)|Python從零開始系列連載(二十)——生成器

這是為什么呢,?

6

send()退化為next()

小紅:老師,,我想了兩天終于想到了!

哦,?你說(shuō)說(shuō)

小紅:因?yàn)?f.send()取生成器第一個(gè)對(duì)象,,并且傳入了一個(gè)參數(shù)‘Python’

但是,并沒(méi)有變量去接收這個(gè)參數(shù),!所以報(bào)錯(cuò)了,!

是的,之前我們的代碼是這樣的:

技術(shù)|Python從零開始系列連載(二十)——生成器

注意,,我們調(diào)用第一個(gè)對(duì)象使用next,,并沒(méi)有傳入?yún)?shù),!

而第二次使用send調(diào)用下一個(gè)對(duì)象時(shí)候,傳入的參數(shù)相當(dāng)于代替了yield i

也就是賦值給了item,,所以沒(méi)報(bào)錯(cuò)

小明:老濕,,你說(shuō)send是加強(qiáng)版的next,我想給send退化到next,,可以么,?

這個(gè)嘛,是可以的,!小明你試試,!

小明:大家都退后!我要裝逼了,!

技術(shù)|Python從零開始系列連載(二十)——生成器

技術(shù)|Python從零開始系列連載(二十)——生成器

小明:不傳參數(shù)竟然不行?。?!

技術(shù)|Python從零開始系列連載(二十)——生成器

小明啊,,應(yīng)該是這樣的!

技術(shù)|Python從零開始系列連載(二十)——生成器

傳入None才對(duì),!

小明:我不服,!老濕,你說(shuō)這生成器很厲害,,具體有啥應(yīng)用呢,?學(xué)了沒(méi)用豈不是很雞肋?

這個(gè)嘛,!其實(shí)是有用的,,我先劇透一下!

技術(shù)|Python從零開始系列連載(二十)——生成器

多任務(wù)——協(xié)程

我們先介紹一下多任務(wù)

多任務(wù)處理是指用戶可以在同一時(shí)間內(nèi)運(yùn)行多個(gè)應(yīng)用程序,每個(gè)應(yīng)用程序被稱作一個(gè)任務(wù)

簡(jiǎn)單點(diǎn)說(shuō),,就是

你現(xiàn)在可能邊看這篇文章邊聽著音樂(lè)

技術(shù)|Python從零開始系列連載(二十)——生成器

而看文章是一個(gè)任務(wù)(這里的任務(wù)指正在做的事情)

聽音樂(lè)也是一個(gè)任務(wù)

你同時(shí)在做這兩件事

就是多任務(wù)啦

電腦和人還是不一樣的

我們今天講一下協(xié)程來(lái)完成多任務(wù)(之后還會(huì)講到線程,、進(jìn)程來(lái)完成多任務(wù))

考慮一個(gè)工廠流水線

A機(jī)器每次將一件貨物放入箱子

B機(jī)器每次將A機(jī)器的箱子封箱打包

為了不產(chǎn)生問(wèn)題,必須A完成一個(gè),,B接著完成一個(gè)

并且看起來(lái)兩個(gè)任務(wù)是同時(shí)執(zhí)行的,!

技術(shù)|Python從零開始系列連載(二十)——生成器

在Python中可以用生成器實(shí)現(xiàn)簡(jiǎn)單的協(xié)程:

技術(shù)|Python從零開始系列連載(二十)——生成器

我們來(lái)看這個(gè)程序,先定義了兩個(gè)生成器(不是函數(shù)哦~原因在之前課程講過(guò))

當(dāng)我們?cè)趙hile主程序中,,先使用f1.__next__( )調(diào)用生成器func1,,因?yàn)閒un1的循環(huán)條件始終為真

所以先打印(執(zhí)行裝入操作)然后遇到 yield 退出生成器func1,,回到主程序

接著執(zhí)行f2.__next__( )調(diào)用生成器func2,像之前調(diào)用func1一樣,,先打?。▓?zhí)行打包操作)

然后遇到y(tǒng)ield退出生成器func2,,回到主程序

因?yàn)橹鞒绦蜓h(huán)條件始終為真,所以繼續(xù)像之前一樣,,接著使用f1.__next__( )調(diào)用生成器func1,。。,。

如此往復(fù),。。,。

我是使用打斷來(lái)停止程序執(zhí)行的,,不然會(huì)不斷執(zhí)行下去

由于兩個(gè)生成器(任務(wù))交替執(zhí)行,很快

就像在多任務(wù)執(zhí)行

所以,,通俗理解看上去同時(shí)執(zhí)行的就是多任務(wù)~

小明:竟然有這種操作,!

今天作業(yè):

敲一遍代碼,理解一下兩種生成器創(chuàng)建方式

自己不敲代碼永遠(yuǎn)學(xué)不會(huì)寫代碼

下課

人生苦短,,我選Python

未完待續(xù),,連載中......

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多