列表生成式&生成器&迭代器:生成器都是迭代器娜汁,迭代器不一定是生成器

https://www.cnblogs.com/yuanchenqi/articles/5769491.html
https://www.cnblogs.com/yyds/p/6281453.html
列表生成式:顧名思義,列表生成式就是一個(gè)用來生成列表的特定語法形式的表達(dá)式婆誓。
基礎(chǔ)語法格式

[exp for iter_var in iterable]

生成器與列表生成式對(duì)比
既然通過列表生成式就可以直接創(chuàng)建一個(gè)新的list捞蛋,那么為什么還要有生成器存在呢?

因?yàn)榱斜砩墒绞侵苯觿?chuàng)建一個(gè)新的list尊惰,它會(huì)一次性地把所有數(shù)據(jù)都存放到內(nèi)存中讲竿,這會(huì)存在以下幾個(gè)問題:

內(nèi)存容量有限,因此列表容量是有限的弄屡;
當(dāng)列表中的數(shù)據(jù)量很大時(shí)题禀,會(huì)占用大量的內(nèi)存空間,如果我們僅僅需要訪問前面有限個(gè)元素時(shí)膀捷,就會(huì)造成內(nèi)存資源的極大浪費(fèi)迈嘹;
當(dāng)數(shù)據(jù)量很大時(shí),列表生成式的返回時(shí)間會(huì)很慢全庸;
而生成器中的元素是按照指定的算法推算出來的秀仲,只有調(diào)用時(shí)才生成相應(yīng)的數(shù)據(jù)。這樣就不必一次性地把所有數(shù)據(jù)都生成壶笼,從而節(jié)省了大量的內(nèi)存空間神僵,這使得其生成的元素個(gè)數(shù)幾乎是沒有限制的,并且操作的返回時(shí)間也是非掣才快速的(僅僅是創(chuàng)建一個(gè)變量而已)保礼。

例如:s=(x*2 for x in range(100)#range(start, stop[, step]),o開始
print(next(s))#等價(jià)于s.next() in py2: s.next() 結(jié)果為0;
print(next(s))#等價(jià)于s.next() in py2: s.next() 結(jié)果為4责语;

生成器(Generator)
生成器就是可迭代對(duì)象炮障;本質(zhì)就是一個(gè)函數(shù)
從名字上來看,生成器應(yīng)該是用來生成數(shù)據(jù)的坤候。

  1. 生成器的作用
    按照某種算法不斷生成新的數(shù)據(jù)胁赢,直到滿足某一個(gè)指定的條件結(jié)束。生成器其實(shí)是一種特殊的迭代器白筹,不過這種迭代器更加優(yōu)雅徘键。
  2. 生成器的構(gòu)造方式
    構(gòu)造生成器的兩種方式:

使用類似列表生成式的方式生成 (2*n + 1 for n in range(3, 11))
使用包含yield的函數(shù)來生成
如果計(jì)算過程比較簡(jiǎn)單,可以直接把列表生成式改成generator遍蟋;但是,如果計(jì)算過程比較復(fù)雜螟凭,就只能通過包含yield的函數(shù)來構(gòu)造generator虚青。

說明: Python 3.3之前的版本中,不允許迭代函數(shù)法中包含return語句螺男。

3. 生成器構(gòu)造實(shí)例#生成器&生成器對(duì)象指的是同一個(gè)意思棒厘,

生成器在創(chuàng)立的時(shí)候就已經(jīng)決定了能計(jì)算出的值得個(gè)數(shù)纵穿,一旦調(diào)用next的次數(shù)超出這個(gè)數(shù)量就會(huì)報(bào)錯(cuò)
1.使用類似列表生成式的方式構(gòu)造生成器
g1 = (2n + 1 for n in range(3, 6))#這是列表生成式產(chǎn)生的生成器(2n + 1 for n in range(3, 6)),還沒有產(chǎn)生數(shù)據(jù)
2.使用包含yield的函數(shù)構(gòu)造生成器
def my_range(start, end):##my_range()是生成器奢人,生成器也是函數(shù)谓媒,range是函數(shù)名
for n in range(start, end):
yield 2*n + 1 #帶有yield的生成器
g2 = my_range(3, 6)
print(type(g1))
print(type(g2))

輸出結(jié)果:

<class 'generator'>
<class 'generator'>

  1. 生成器的執(zhí)行過程與特性
    生成器的執(zhí)行過程:
    在執(zhí)行過程中,遇到y(tǒng)ield關(guān)鍵字就會(huì)中斷執(zhí)行何乎,下次調(diào)用則繼續(xù)從上次中斷的位置繼續(xù)執(zhí)行句惯。

生成器的特性:
只有在調(diào)用時(shí)才會(huì)生成相應(yīng)的數(shù)據(jù)
只記錄當(dāng)前的位置
只能next,不能prev

5. 生成器的調(diào)用方式或者方法

要調(diào)用生成器產(chǎn)生新的元素支救,有兩種方式:

調(diào)用內(nèi)置的next()方法

使用循環(huán)對(duì)生成器對(duì)象進(jìn)行遍歷(推薦)
for循環(huán)內(nèi)部做了三件事:
1.調(diào)用對(duì)象的iter方法抢野,返回一個(gè)迭代器對(duì)象

  1. while:
                try:
                      i=next (list_Iterator)
                       except  stopIteration:
                                    break
    

調(diào)用生成器對(duì)象的send()方法
send():
f().send(None)#等價(jià)于next(f())

s=(2*n + 1 for n in range(3, 11))
print(s)#生成器<generator object <genexpr> at 0x000001E63FFE0DD0>
print(next(s))#等價(jià)于s.next() in Py2: s.next()
print(next(s))
print(next(s))
print(next(s))#工作過程:# 迭代iterable中的每個(gè)元素;# 每次迭代都先把結(jié)果賦值給iter_var各墨,然后通過exp得到一個(gè)新的計(jì)算值指孤;# 最后把所有通過exp得到的計(jì)算值以一個(gè)新列表的形式返回。
print(next(s))
print(next(s))
print(next(s))
print(next(s))
print(next(s))#StopIteration
可見贬堵,使用next()方法遍歷生成器時(shí)恃轩,當(dāng)超出遍歷范圍,最后是以拋出一個(gè)StopIeration異常終止黎做。

實(shí)例2:使用循環(huán)遍歷生成器

g1 = (2*n + 1 for n in range(3, 6))#3,4,5
for x in g1:
print(x)
輸出結(jié)果是
7
9
11
可見叉跛,使用循環(huán)遍歷生成器時(shí)比較簡(jiǎn)潔,且最后不會(huì)拋出一個(gè)StopIeration異常引几。因此使用循環(huán)的方式遍歷生成器的方式才是被推薦的昧互。
需要說明的是:如果生成器函數(shù)有返回值,要獲取該返回值的話伟桅,只能通過在一個(gè)while循環(huán)中不斷的next()敞掘,最后通過捕獲StopIteration異常

實(shí)例3:調(diào)用生成器對(duì)象的send()方法

def my_range(start, end):
for n in range(start, end):
ret = yield 2*n + 1
print(ret)
g3 = my_range(3, 6)

print(g3.send(None))
print(g3.send('hello01'))
print(g3.send('hello02'))
輸出結(jié)果:
7
hello01
9
hello02
11
print(next(g3))
print(next(g3))
print(next(g3))
輸出結(jié)果:
7
None
9
None
11

結(jié)論:
next()會(huì)調(diào)用yield,但不給它傳值
send()會(huì)調(diào)用yield楣铁,也會(huì)給它傳值(該值將成為當(dāng)前yield表達(dá)式的結(jié)果值)
需要注意的是:第一次調(diào)用生成器的send()方法時(shí)玖雁,參數(shù)只能為None,否則會(huì)拋出異常盖腕。當(dāng)然也可以在調(diào)用send()方法之前先調(diào)用一次next()方法赫冬,目的是讓生成器先進(jìn)入yield表達(dá)式。
https://www.cnblogs.com/alex3714/articles/5143440.html

可迭代對(duì)象(Iterable)

我們經(jīng)常在Python的文檔中看到“Iterable”這個(gè)此溃列,它的意思是“可迭代對(duì)象”劲厌。那么什么是可迭代對(duì)象呢?

可直接用于for循環(huán)的對(duì)象統(tǒng)稱為可迭代對(duì)象听隐;本質(zhì)上是有iter方法的是可迭代對(duì)象(Iterable)补鼻。
滿足迭代器協(xié)議:
1.內(nèi)部有next方法
2.內(nèi)部有iter()方法

目前我們已經(jīng) 知道的可迭代(可用于for循環(huán))的數(shù)據(jù)類型有,本質(zhì)上是內(nèi)部有iter方法!!7绶丁:
li=[1,2,3]: iterable(內(nèi)部有iter方法)>>>>>>
i=iter(li):list_Iterator#i是迭代器對(duì)象
集合數(shù)據(jù)類型:如list咨跌、tuple、dict硼婿、set锌半、str等生成器(Generator)
可以使用isinstance()來判斷一個(gè)對(duì)象是否是Iterable對(duì)象:

from collections import Iterable
print(isinstance([], Iterable))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市寇漫,隨后出現(xiàn)的幾起案子刊殉,更是在濱河造成了極大的恐慌,老刑警劉巖猪腕,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冗澈,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡陋葡,警方通過查閱死者的電腦和手機(jī)亚亲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腐缤,“玉大人捌归,你說我怎么就攤上這事×朐粒” “怎么了惜索?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)剃浇。 經(jīng)常有香客問我巾兆,道長(zhǎng),這世上最難降的妖魔是什么虎囚? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任角塑,我火速辦了婚禮,結(jié)果婚禮上淘讥,老公的妹妹穿的比我還像新娘圃伶。我一直安慰自己,他們只是感情好蒲列,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布窒朋。 她就那樣靜靜地躺著,像睡著了一般蝗岖。 火紅的嫁衣襯著肌膚如雪侥猩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天抵赢,我揣著相機(jī)與錄音欺劳,去河邊找鬼洛退。 笑死,一個(gè)胖子當(dāng)著我的面吹牛杰标,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播彩匕,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼腔剂,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了驼仪?” 一聲冷哼從身側(cè)響起掸犬,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绪爸,沒想到半個(gè)月后湾碎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奠货,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年介褥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片递惋。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡柔滔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出萍虽,到底是詐尸還是另有隱情睛廊,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布杉编,位于F島的核電站超全,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏邓馒。R本人自食惡果不足惜嘶朱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绒净。 院中可真熱鬧见咒,春花似錦、人聲如沸挂疆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缤言。三九已至宝当,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胆萧,已是汗流浹背庆揩。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工俐东, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人订晌。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓虏辫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锈拨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子砌庄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349