摘要:原文我的微信公眾號(hào)每日一練要理解什么是,必須理解什么是生成器。在理解生成器之前,讓我們先了解迭代。直到運(yùn)行到函數(shù)結(jié)尾處停止,此時(shí)如果是用則會(huì)拋出異常,如果是用則會(huì)結(jié)束循環(huán)并且不會(huì)有異常
原文:https://stackoverflow.com/que...我的微信公眾號(hào):python每日一練
要理解什么是 yield,必須理解什么是生成器(generator)。在理解生成器之前,讓我們先了解迭代。
迭代
當(dāng)你建立了一個(gè)列表,你可以逐個(gè)地訪問這個(gè)列表的元素,而這個(gè)訪問的過程叫做迭代(iteration)
>>> mylist = [1, 2, 3] >>> for i in mylist: ... print(i) 1 2 3
代碼中的mylist就是一個(gè)可迭代對(duì)象(iterable),當(dāng)你使用列表生成式時(shí),你就創(chuàng)建了一個(gè)list,同時(shí)也創(chuàng)建了一個(gè)可迭代對(duì)象:
>>> mylist = [x*x for x in range(3)] >>> for i in mylist: ... print(i) 0 1 4
凡是能使用for...in...語句的對(duì)象,都叫做可迭代對(duì)象,例如:list、string、文件等等
這些可迭代對(duì)象非常方便,因?yàn)槟憧梢愿鶕?jù)自己的需要來訪問它們。但是同時(shí)也需要將所有的值存入內(nèi)存當(dāng)中,無論你是不是需要所有的值,可能對(duì)于一個(gè)列表[x for x in range(100000)],你僅僅想拿到里面的素?cái)?shù),但當(dāng)這個(gè)列表生成式被執(zhí)行的時(shí)候,已經(jīng)將所有100000個(gè)數(shù)字存入了內(nèi)存中。
生成器
生成器是一種只能迭代一次的迭代器,生成器不會(huì)一次將所有的元素存入內(nèi)存中,而是一邊迭代一邊運(yùn)算:
>>> mygenerator = (x*x for x in range(3)) >>> for i in mygenerator: ... print(i) 0 1 4
這份代碼看起來和上面的代碼沒有什么區(qū)別。但是你不能再次執(zhí)行for i in mygenerator,因?yàn)樯善髦荒苁褂靡淮危?/p>
>>> mygenerator = (x*x for x in range(3)) >>> for i in mygenerator: ... print(i) ... 0 1 4 >>> for i in mygenerator: ... print(i) ... >>>
Yield
yield的使用和return的使用沒什么區(qū)別,只是yield會(huì)返回一個(gè)生成器
>>> def createGenerator(): ... mylist = range(3) ... for i in mylist: ... yield i*i ... >>> mygenerator = createGenerator() # 創(chuàng)建一個(gè)生成器 >>> print(mygenerator) # mygenerator是一個(gè)對(duì)象!>>> for i in mygenerator: ... print(i) 0 1 4
當(dāng)你的函數(shù)需要返回一個(gè)很大的元素集合,并且每個(gè)元素只需要用到一次的時(shí)候,使用yield會(huì)非常方便
要想理解yield,你必須理解當(dāng)你調(diào)用一個(gè)包含yield的函數(shù)的時(shí)候,函數(shù)體代碼并不會(huì)執(zhí)行,這個(gè)函數(shù)僅僅是返回一個(gè)生成器而已
>>> def createGenerator(): ... print("head") ... for i in range(5): ... yield i*i ... print("tail") ... >>> createGenerator()
當(dāng)你第一次向后迭代(用next或for...in...語句時(shí))這個(gè)生成器時(shí),函數(shù)體才會(huì)從最開始執(zhí)行到yield處然后返回yield的值,隨后再次向后迭代,會(huì)執(zhí)行剩余的代碼然后再次遇到yield停止并返回值。直到運(yùn)行到函數(shù)結(jié)尾處停止,此時(shí)如果是用next()則會(huì)拋出StopIteration異常,如果是用for...in...則會(huì)結(jié)束循環(huán)并且不會(huì)有異常
>>> def createGenerator(): ... print("head") ... for i in range(5): ... yield i*i ... print("tail") ... >>> g = createGenerator() >>> next(g) head 0 >>> next(g) 1 >>> next(g) 4 >>> next(g) 9 >>> next(g) 16 >>> next(g) tail Traceback (most recent call last): File "", line 1, in StopIteration
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/41617.html
摘要:第四種選擇是在不同的線程中運(yùn)行生產(chǎn)者和消費(fèi)者。包含語句的函數(shù)被稱為生成器函數(shù)。然后引發(fā)一個(gè)異常,表明迭代器已經(jīng)耗盡。換句話說,未捕獲的異常終結(jié)了生成器的使用壽命。 showImg(https://segmentfault.com/img/bVbntUq?w=4272&h=2848);我正打算寫寫 Python 的生成器,然而查資料時(shí)發(fā)現(xiàn),引入生成器的 PEP 沒人翻譯過,因此就花了點(diǎn)時(shí)...
摘要:提議以下的新的生成器語法將被允許在生成器的內(nèi)部使用其中表達(dá)式作用于可迭代對(duì)象,從迭代器中提取元素。子迭代器而非生成器的語義被選擇成為生成器案例的合理泛化。建議如果關(guān)閉一個(gè)子迭代器時(shí),引發(fā)了帶返回值的異常,則將該值從調(diào)用中返回給委托生成器。 導(dǎo)語: PEP(Python增強(qiáng)提案)幾乎是 Python 社區(qū)中最重要的文檔,它們提供了公告信息、指導(dǎo)流程、新功能的設(shè)計(jì)及使用說明等內(nèi)容。對(duì)于學(xué)習(xí)...
閱讀 3629·2021-09-22 15:50
閱讀 3288·2019-08-30 15:54
閱讀 2818·2019-08-30 14:12
閱讀 3122·2019-08-30 11:22
閱讀 2145·2019-08-29 11:16
閱讀 3632·2019-08-26 13:43
閱讀 1263·2019-08-23 18:33
閱讀 978·2019-08-23 18:32