Python3?中return和yield的區(qū)別
一、前言
return一直中,每中語言中其沒沒有很大差別,就不多說了。(shell語言return的是退出狀態(tài),可能差別是比較大的)最早看到y(tǒng)ield應(yīng)該是哪們語言用來調(diào)整什么線程優(yōu)先級的,記不清了,不過那里的yield和python中的yield應(yīng)該功能有區(qū)別。
python中最早看到y(tǒng)ield應(yīng)該是使用scrapy框架寫爬蟲的時候,之前也有去看yiled的用法,總記不太住。今天又去看了一下,基本上來就是講些斐波那契數(shù)列的煩的要死,自己寫段程序研究了一下,這里記一下。
二、return和yield的異同
共同點:return和yield都用來返回值;在一次性地返回所有值場景中return和yield的作用是一樣的。
不同點:如果要返回的數(shù)據(jù)是通過for等循環(huán)生成的迭代器類型數(shù)據(jù)(如列表、元組),return只能在循環(huán)外部一次性地返回,yeild則可以在循環(huán)內(nèi)部逐個元素返回。下邊我們舉例說明這個不同點。
三、實例說明
1 return版本
示例代碼如下:
class TestYield: def gen_iterator(self): result_list = [] for j in range(3): print(f"gen_iterator-{j}") result_list.append(j) # return在循環(huán)的外部,待變量完全生成后一次性返回 return result_list def call_gen_iterator(self): # 執(zhí)行下邊這句后result_list直接是完成的結(jié)果[0,1,2] result_list = self.gen_iterator() for i in result_list: print(f"call_gen_iterator-{i}") if __name__ == "__main__": obj = TestYield() obj.call_gen_iterator()
執(zhí)行結(jié)果如下,可以看到一次性執(zhí)行完下層函數(shù),生成完整的迭代器類型返回值result_list,一次性返回給上層函數(shù):
2 yield版本
示例代碼如下:
class TestYield: def gen_iterator(self): for j in range(3): print(f"do_something-{j}") # yield在for循環(huán)內(nèi)部 yield j def call_gen_iterator(self): # yield并不是直接返回[0,1,2],執(zhí)行下邊這句后result_list什么值都沒有 result_list = self.gen_iterator() # i每請求一個數(shù)據(jù),才會觸發(fā)gen_iterator生成一個數(shù)據(jù) for i in result_list: print(f"call_gen_iterator-{i}") if __name__ == "__main__": obj = TestYield() obj.call_gen_iterator()
執(zhí)行結(jié)果如下,可以看到上下層函數(shù)是交替進行的,即上層函數(shù)請求迭代一個值下層函數(shù)才生成一個值并立即返回這個值:
3 yield的意義
從上邊兩個小節(jié)可以看到,雖然return和yield兩者執(zhí)行的順序有區(qū)別,但整個要做的事情是一樣的,所以使用yield并不會比return快,甚至我們可以猜測由于yield總發(fā)生上下文切換在速度上還會慢一些,所以速度不是yield的意義。
他們的主要區(qū)別是yiled要迭代到哪個元素那個元素才即時地生成,而return要用一個中間變量result_list保存返回值,當result_list的長度很長且每個組成元素內(nèi)容很大時將會耗費比較大的內(nèi)存,此時yield相對return才有優(yōu)勢。
四、yield和return嵌套使用
class TestYield: def gen_iterator(self): for j in range(3): print(f"do_something-{j}") # yield在for循環(huán)內(nèi)部 yield j def gen_iterator_middle(self): print(f"gen_iterator_middle") # 返回的是迭代器的句柄,所以加一層return不影響是可以理解的 return self.gen_iterator() def call_gen_iterator(self): # yield并不是直接返回[0,1,2],執(zhí)行下邊這句后result_list什么值都沒有 result_list = self.gen_iterator_middle() # i每請求一個數(shù)據(jù),才會觸發(fā)gen_iterator生成一個數(shù)據(jù) for i in result_list: print(f"call_gen_iterator-{i}") if __name__ == "__main__": obj = TestYield() obj.call_gen_iterator()
到此這篇關(guān)于Python3 中return和yield的區(qū)別的文章就介紹到這了,更多相關(guān)Python return和yield 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django框架實現(xiàn)在線考試系統(tǒng)的示例代碼
這篇文章主要介紹了Django框架實現(xiàn)在線考試系統(tǒng)的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2020-11-11python3 動態(tài)模塊導(dǎo)入與全局變量使用實例
今天小編就為大家分享一篇python3 動態(tài)模塊導(dǎo)入與全局變量使用實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12Flask使用SQLAlchemy實現(xiàn)持久化數(shù)據(jù)
本文主要介紹了Flask使用SQLAlchemy實現(xiàn)持久化數(shù)據(jù),文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2021-07-07對pandas中時間窗函數(shù)rolling的使用詳解
今天小編就為大家分享一篇對pandas中時間窗函數(shù)rolling的使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11使用Streamlit和Pandas實現(xiàn)帶有可點擊鏈接的數(shù)據(jù)表格
這篇文章主要為大家詳細介紹了如何利用?Streamlit?和?Pandas?在?Python?中創(chuàng)建一個帶有可點擊鏈接的數(shù)據(jù)表格,感興趣的小伙伴可以跟隨小編一起學(xué)習一下2023-11-11tensorflow 實現(xiàn)自定義layer并添加到計算圖中
今天小編就為大家分享一篇tensorflow 實現(xiàn)自定義layer并添加到計算圖中,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02