迭代器和生成器

迭代器

什么是迭代協(xié)議徒欣?
迭代器是什么打肝?迭代器是訪問集合內(nèi)元素的一種方式颂龙,一般用來遍歷數(shù)據(jù)
迭代器和以下標(biāo)的訪問方式不一樣并鸵。迭代器是不能返回的泰鸡,迭代器提供了一種惰性方式訪問數(shù)據(jù)

任何實(shí)現(xiàn)了iter或者getitem的都是可迭代對(duì)象

class Company(object):

    def __init__(self, employee_list):
        self.employees = employee_list

    def __getitem__(self, item):
        return self.employees[item]


company = Company(['張三', '李四', '王五'])
print(isinstance(company, Iterable))
# 執(zhí)行結(jié)果:False
print(isinstance(company, Iterator))
# 執(zhí)行結(jié)果:False
for c in company:
    print(c)
執(zhí)行結(jié)果:
    張三
    李四
    王五

對(duì)于for循環(huán)來說,首先尋找iter方法醉锅,如果沒有iter方法硬耍,那么就會(huì)去尋找getitem方法,這個(gè)方法是用來定義序列用的甚纲,
如果兩個(gè)方法都沒有介杆,那么就說這個(gè)對(duì)象是不可迭代的。只要實(shí)現(xiàn)了這兩個(gè)方法中的其中一個(gè)荆隘,就證明這個(gè)對(duì)象是可迭代對(duì)象赴背。
如果有iter方法,就會(huì)得到一個(gè)迭代器對(duì)象燃观,然后調(diào)用迭代器的next方法便瑟,獲取元素脊框,直到拋出StopIteration異常為止浇雹,for循環(huán)本身
會(huì)對(duì)這種異常作出處理箫爷。如果有getitem方法虎锚,那么就從下標(biāo)0開始獲取數(shù)據(jù)窜护。
疑問:只有getitem的類的實(shí)例是屬于可迭代對(duì)象非春,但用isinstances測(cè)試collections.Iterable是不能通過的奇昙,可以通過iter函數(shù)來測(cè)試,
如果沒報(bào)錯(cuò)就說明是可迭代對(duì)象羊初,然后生成一個(gè)沒有next屬性的迭代器晦攒。

print(dir(company))
'''
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
'__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', 
'__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'employees']
'''

迭代器需要實(shí)現(xiàn)iternext,iter用來返回一個(gè)迭代器脯颜,next用來獲取下一個(gè)元素和拋出StopIteration的異常栋操。
備注:內(nèi)置函數(shù)iter()調(diào)用的是iter方法乐设,next()調(diào)用的是next方法

class Company(object):

    def __init__(self, employee_list):
        self.employees = employee_list

    def __iter__(self):
        return MyIterator(self.employees)


class MyIterator():

    def __init__(self, iter_list):
        self.iter_list = iter_list
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        try:
            res = self.iter_list[self.index]
        except IndexError:
            raise StopIteration
        self.index += 1
        return res


company = Company(['張三', '李四', '王五'])
print(isinstance(company, Iterable))
# 執(zhí)行結(jié)果:True
print(isinstance(company, Iterator))
# 執(zhí)行結(jié)果:False

my_iterator = MyIterator(['張三', '李四', '王五'])
print(isinstance(my_iterator, Iterable))
# 執(zhí)行結(jié)果:True
print(isinstance(my_iterator, Iterator))
# 執(zhí)行結(jié)果:True
for em in company:
    print(em)
'''
執(zhí)行結(jié)果
    張三
    李四
    王五
'''

生成器

生成器函數(shù):函數(shù)里面只要有yield關(guān)鍵字蠕啄,那么這就是一個(gè)生成器函數(shù)
生成器函數(shù)最開始調(diào)用的時(shí)候戈锻,返回的是一個(gè)生成器對(duì)象格遭,在python編譯字節(jié)碼的時(shí)候就產(chǎn)生了這個(gè)生成器對(duì)象
生成器函數(shù)也可以return一個(gè)值

生成器函數(shù)會(huì)在內(nèi)部記錄函數(shù)執(zhí)行的字節(jié)碼的位置骚秦,生成器函數(shù)也是分配在堆內(nèi)存當(dāng)中的
調(diào)用生成器函數(shù)作箍,函數(shù)并不會(huì)馬上執(zhí)行胞得,調(diào)用next方法或者用for驅(qū)動(dòng)生成器的執(zhí)行.
如果next方法取不到值了屹电,則要給一個(gè)默認(rèn)值,否則會(huì)報(bào)StopIteration的錯(cuò)誤牧愁。
在生成器函數(shù)中外莲,函數(shù)執(zhí)行遇到y(tǒng)ield會(huì)掛起办龄,返回yield右邊的值,直到下一次生成器再次被驅(qū)動(dòng)俐填。send方法也可以驅(qū)動(dòng)生成器函數(shù)英融。

def foo():
    yield 1
    name = 'bobby'
    yield 2
    age = 18
    return 30


f = foo()
print(isinstance(f, Generator))
# 執(zhí)行結(jié)果:True
print(next(f))
# 執(zhí)行結(jié)果:1
print(next(f))
# 執(zhí)行結(jié)果:2
print(next(f, 'Over'))

捕獲生成器的返回值

def foo():
    yield 1
    name = 'bobby'
    yield 2
    age = 18
    return 30
f = foo()
while True:
    try:
        x = next(f)
        print(x)
    except StopIteration as e:
        print('StopIteration:',e.value)
        break
'''
執(zhí)行結(jié)果:
    1
    2
    StopIteration: 30
'''s
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市痕鳍,隨后出現(xiàn)的幾起案子龙巨,更是在濱河造成了極大的恐慌,老刑警劉巖诗赌,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铭若,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡环鲤,警方通過查閱死者的電腦和手機(jī)憎兽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門纯命,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人亿汞,你說我怎么就攤上這事∧衔妫” “怎么了溺健?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)岭辣。 經(jīng)常有香客問我沦童,道長(zhǎng)搞动,這世上最難降的妖魔是什么渣刷? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任辅柴,我火速辦了婚禮碌嘀,結(jié)果婚禮上霹陡,老公的妹妹穿的比我還像新娘止状。我一直安慰自己浆洗,他們只是感情好伏社,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布摘昌。 她就那樣靜靜地躺著速妖,像睡著了一般买优。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上湘纵,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音铺敌,去河邊找鬼偿凭。 笑死弯囊,一個(gè)胖子當(dāng)著我的面吹牛匾嘱,可吹牛的內(nèi)容都是我干的早抠。 我是一名探鬼主播蕊连,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼盗忱,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼趟佃!你這毒婦竟也來了罐寨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤簸淀,失蹤者是張志新(化名)和其女友劉穎瓶蝴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體租幕,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舷手,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了劲绪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片男窟。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖汗捡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站雕薪,受9級(jí)特大地震影響燥爷,放射性物質(zhì)發(fā)生泄漏港华。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忿晕。 院中可真熱鬧咕幻,春花似錦选浑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咖刃。三九已至磕潮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間轻纪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工赦抖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留交胚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓替废,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親孙咪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 定位元素 position static 默認(rèn)屬性拷窜。元素按常規(guī)的文檔內(nèi)容流恋谭,從左到右均抽、從上到下進(jìn)行定位款熬。不能使用t...
    河的左岸閱讀 248評(píng)論 0 0
  • 《為自己讀書》 要相信你到這個(gè)世界來是有目的的。 是為了造就自己刽沾,是為了幫助別人,是為了扮演一個(gè)別人替代不了的角色...
    一花匠閱讀 938評(píng)論 1 1
  • RingBuffer的最大容量璧榄,必須是創(chuàng)建Disruptor對(duì)象指定消費(fèi)者特漩,其中消費(fèi)者3必須在消費(fèi)者1和消費(fèi)者2同...
    menghuijia閱讀 546評(píng)論 0 0