最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你探尋Python中的生成器

 更新時(shí)間:2023年04月11日 09:32:04   作者:真的不能告訴你我的名字  
這篇文章就來和大家詳細(xì)講一講Python中生成器的的相關(guān)知識,文中的示例代碼講解詳細(xì),對我們深入了解Python有一定的幫助,感興趣的可以了解一下

面試官: 聽說你熟悉python,那么你能簡單闡述一下python的裝飾器、生成器以及迭代器么?

我: emm, 我不清楚,我只是了解過python最基本的代碼。

上述是弟弟前段時(shí)間去面試運(yùn)維開發(fā),遇到的問題,emmm,運(yùn)維是一個很雜的職業(yè),在小公司,總結(jié)一句話就是寬而淺,痛定思痛,決定來了解一下python特性,于是乎,就有了這篇文章。

這邊文章,我們將介紹python生成器,使用環(huán)境為: Python 3.6.8

如果你還沒有了解過迭代器,建議查看迭代器的文章:《python | 你知道for...in是底層原理是什么樣的么?探尋python迭代器》

什么是python生成器

上一篇文章我們介紹了迭代器,而生成器是一種特殊的迭代器,它內(nèi)部也有__iter__方法和__next__方法,在終止生成器的時(shí)候,還是會拋StopIteration異常以此來退出循環(huán),只不過相比于迭代器,生成器還有特性會保存“中間值”,下次運(yùn)行的時(shí)候,還會借助這個“中間值”來操作。生成器的關(guān)鍵字是yield,我們下面來寫一個最簡單的生成器。

#!/usr/bin/env python

def printNums():
    i = 0
    while i<10:
        yield i
        i = i + 1


def main():
    for i in printNums():
        print(i)

if __name__ == '__main__':
    main()

粗看代碼,可能會覺著這個是個啥啊,為啥不直接用range來生成,偏偏要用yield,哎,不急,我們接著往下看為什么需要生成器,或者說,生成器解決了什么問題。

為什么需要python生成器

在說明這個問題之前,我們先來寫一個需求,輸出 0——10000000 以內(nèi)的數(shù)據(jù),而后運(yùn)行查看導(dǎo)出內(nèi)存運(yùn)行截圖。

調(diào)用python程序內(nèi)存信息輔助說明

這里可以借助pythonmemory_profiler模塊來檢測程序內(nèi)存的占用情況。

安裝memory_profiler庫:

pip3 install memory_profiler

使用方法很簡單,在需要檢測的函數(shù)或者是代碼前添加@profile裝飾器即可,例如:

@profile
def main():
    pass

生成.dat文件

mprof run <executable>

導(dǎo)出圖示,可以使用

mprof plot --output=filename

python案例代碼

以下2個程序,都是輸出0—9999999之間的數(shù)據(jù),不同的是,第一個程序是使用range而后給append進(jìn)list中,第二個則是使用迭代器來生成該數(shù)據(jù)。

main.py程序

@profile
def main():
    data = list(range(10000000))
    for i in data:
        pass

if __name__ == '__main__':
    main()

main_2.py程序

def printNum():
    i = 0 
    while i < 10000000:
        yield i
        i = i + 1

@profile
def main():
    for i in printNum():
        pass

if __name__ == '__main__':
    main()

運(yùn)行程序

代碼也有了,就可以按照上述來運(yùn)行一下程序,并且導(dǎo)出內(nèi)存信息

運(yùn)行后內(nèi)存信息查看

main.py 運(yùn)行內(nèi)存圖

main_2.py 運(yùn)行內(nèi)存圖

如上2張對比圖,當(dāng)我們將數(shù)據(jù)疊加進(jìn)列表,再輸出的時(shí)候,占用內(nèi)存接近400M,而使用迭代器來計(jì)算下一個值內(nèi)存僅使用16M。

通過上述案例,我們應(yīng)該知道為什么要使用生成器了吧。

python生成器原理

由于生成器表達(dá)式yield語句涉及到了python解釋權(quán)內(nèi)部機(jī)制,所以很難查看其源碼,很難獲取其原理,不過我們可以利用yield的暫停機(jī)制,來探尋一下生成器。

可以編寫如下代碼:

def testGenerator():
    print("進(jìn)入生成器")
    yield "pdudo"
    print("第一次輸出")
    yield "juejin"
    print("第二次輸出")

def main():
    xx = testGenerator()
    print(next(xx))
    print(next(xx))

if __name__ == '__main__':
    main()

運(yùn)行后效果如下

通過上述實(shí)例,再結(jié)合下面這段生成器的運(yùn)行過程,會加深對生成器的感觸。

當(dāng)python遇到yield語句時(shí),會記錄當(dāng)前函數(shù)的運(yùn)行狀態(tài),并且暫停執(zhí)行,將結(jié)果拋出。會持續(xù)等待下一次調(diào)用__next__方法,該方法調(diào)用后,會恢復(fù)函數(shù)的運(yùn)行,直至下一個yield語句或者函數(shù)結(jié)束,執(zhí)行到最后沒有yield函數(shù)可執(zhí)行的時(shí)候,會拋StopIteration來標(biāo)志生成器的結(jié)束。

生成器表達(dá)式

python中,生成器除了寫在函數(shù)中,使用yield返回之外,還可以直接使用生成器表達(dá)式,額。。??赡芎艹橄螅悄憧聪旅孢@段代碼,你就明白了。

def printNums():
    for i in [1,2,3,4,5]:
        yield i

def main():
    for i in printNums():
        print(i)

    gener = (i for i in [1,2,3,4,5])
    for i in gener:
        print(i)

if __name__ == '__main__':
    main()

其中,代碼(i for i in [1,2,3,4,5])就等同于printNums函數(shù),其類型都是生成器,我們可以使用type打印出來看下。

改下代碼,輸出結(jié)果如下:

好了,生成器表達(dá)式其實(shí)不復(fù)雜,暫時(shí)就講到這里。

總結(jié)

該篇文章是介紹python生成器,所謂的生成器其實(shí)也是一個特殊的迭代器,其底層依然有__iter____next__方法,不僅如此,它還可以將函數(shù)“暫停”,當(dāng)遇到_next__后,又從上一次暫停的地方開始執(zhí)行,既然是一個特殊的迭代器,所以還是會引發(fā)StopIteration異常。而后介紹了為什么需要生成器,距了一個例子,分別打印0——n個數(shù),一個使用生成器 還有一個 使用list,當(dāng)然list會更加耗費(fèi)內(nèi)存,最后介紹了生成器原理 以及 生成器表達(dá)式。

到此這篇關(guān)于一文帶你探尋Python中的生成器的文章就介紹到這了,更多相關(guān)Python生成器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python使用asyncio實(shí)現(xiàn)異步操作的示例

    Python使用asyncio實(shí)現(xiàn)異步操作的示例

    本文主要介紹了Python使用asyncio實(shí)現(xiàn)異步操作的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • python使用Plotly繪圖工具繪制氣泡圖

    python使用Plotly繪圖工具繪制氣泡圖

    這篇文章主要為大家詳細(xì)介紹了python使用Plotly繪圖工具繪制氣泡圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • python實(shí)現(xiàn)多線程并得到返回值的示例代碼

    python實(shí)現(xiàn)多線程并得到返回值的示例代碼

    這篇文章主要介紹了python實(shí)現(xiàn)多線程并得到返回值的相關(guān)知識,包括帶有返回值的多線程及實(shí)現(xiàn)過程解析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • 用Python編寫一個簡單的Lisp解釋器的教程

    用Python編寫一個簡單的Lisp解釋器的教程

    這篇文章主要介紹了用Python編寫一個簡單的Lisp解釋器的教程,Lisp是一種源碼簡單的函數(shù)式編程語言,本文主要介紹對其中的一個子集Scheme的解釋器開發(fā),需要的朋友可以參考下
    2015-04-04
  • Python使用openpyxl讀寫excel文件的方法

    Python使用openpyxl讀寫excel文件的方法

    本篇文章主要介紹了Python使用openpyxl讀寫excel文件的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Python變量類型知識點(diǎn)總結(jié)

    Python變量類型知識點(diǎn)總結(jié)

    在本文里我們給大家分析一篇關(guān)于Python變量類型的相關(guān)知識點(diǎn)內(nèi)容,需要的朋友們跟著學(xué)習(xí)下。
    2019-02-02
  • python爬蟲之基金信息存儲

    python爬蟲之基金信息存儲

    這篇文章主要介紹了python爬蟲之基金信息存儲,前面已經(jīng)講了很多次要進(jìn)行數(shù)據(jù)存儲,終于在上一篇中完成了數(shù)據(jù)庫的設(shè),在這篇文章我們就來完成數(shù)據(jù)存儲操作部分的介紹,需要的朋友可以參考一下
    2022-05-05
  • django 文件上傳功能的相關(guān)實(shí)例代碼(簡單易懂)

    django 文件上傳功能的相關(guān)實(shí)例代碼(簡單易懂)

    這篇文章主要介紹了django 文件上傳功能的相關(guān)實(shí)例代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 基于Python共軛梯度法與最速下降法之間的對比

    基于Python共軛梯度法與最速下降法之間的對比

    這篇文章主要介紹了基于Python共軛梯度法與最速下降法之間的對比,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • 一文帶你了解Python中的注釋及變量

    一文帶你了解Python中的注釋及變量

    這篇文章主要給大家介紹了關(guān)于Python中注釋及變量的相關(guān)資料,Python是一門動態(tài)類型的語言,因此無須提前聲明變量類型,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07

最新評論

含山县| 普宁市| 洪湖市| 刚察县| 六安市| 石门县| 汝城县| 宜城市| 通许县| 驻马店市| 刚察县| 苗栗市| 河津市| 绥棱县| 黄石市| 东海县| 鹤岗市| 英超| 固阳县| 清原| 延川县| 漾濞| 新宁县| 嵊泗县| 潞城市| 紫云| 古交市| 尚志市| 葵青区| 临沧市| 洞口县| 扶余县| 紫云| 恩施市| 平谷区| 容城县| 上蔡县| 徐水县| 临桂县| 澜沧| 西华县|