欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python筆記003-生成器和生成器表達式

系統(tǒng) 2191 0

Python筆記003-生成器和生成器表達式

以下是我學(xué)習(xí)《流暢的Python》后的個人筆記,現(xiàn)在拿出來和大家共享,希望能幫到各位Python學(xué)習(xí)者。

首次發(fā)表于: 微信公眾號:科技老丁哥,ID: TechDing,敬請關(guān)注。

本篇主要知識點:

  1. 生成器使用yield做關(guān)鍵字,一次只返回一個值給調(diào)用者,然后暫停執(zhí)行,其作用是:節(jié)省內(nèi)存空間。

  2. 生成器可以用next()函數(shù),也可以用for迭代的方式獲取元素值,中間還可以用close()來隨時終止生成器。

  3. 生成器表達式可以認為是一種特殊的生成器,其代碼更簡潔,更容易理解,且和別的函數(shù)結(jié)合會更加靈活。

1. 生成器

生成器是Python中一個特殊的程序,用于控制循環(huán)的迭代行為。相對于一般函數(shù)用return來一次性返回所有值,生成器使用yield關(guān)鍵字,一次只返回一個值。

這樣的設(shè)計有很大的好處:在數(shù)據(jù)處理時,如果函數(shù)return出來的是一個非常大的數(shù)組,那么會非常占用內(nèi)存,有時會報MemoryError的錯誤,而使用yield后一次僅僅返回一個元素值,可以優(yōu)化內(nèi)存占用的情況。

從這種角度來講,生成器函數(shù)每一次調(diào)用都返回一個元素值,這種特性使得生成器長得像函數(shù),但行為卻像迭代器。

            
              
                def
              
              
                squares
              
              
                (
              
              x
              
                )
              
              
                :
              
              
                # 計算0-x的所有數(shù)的平方
              
              
                #     return [i*i for i in range(x)] # 普通寫法,一次返回一個list,包含所有元素
              
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              x
              
                )
              
              
                :
              
              
                yield
              
               i
              
                *
              
              i 
              
                # 生成器:一次只返回一個值
              
              
                print
              
              
                (
              
              squares
              
                (
              
              
                5
              
              
                )
              
              
                )
              
              
                # 
                
              
              
                # 獲取生成器中的元素值
              
              
                for
              
               value 
              
                in
              
               squares
              
                (
              
              
                5
              
              
                )
              
              
                :
              
              
                # 行為類似于迭代器,循環(huán)獲取元素值
              
              
                print
              
              
                (
              
              
                'value: '
              
              
                ,
              
              value
              
                )
              
            
          

生成器并不像一般的函數(shù),它返回一個值后,生成器函數(shù)會自動掛起,等到下一次調(diào)用時(使用其內(nèi)部成員方法 __next__ 來實現(xiàn)),再返回到這個函數(shù)中繼續(xù)執(zhí)行。

所以要想獲取生成器的元素值,需要通過成員方法next()來進行,比如:

            
              square_five
              
                =
              
              squares
              
                (
              
              
                5
              
              
                )
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # 0
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # 1
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # 4
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # 9
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # 16
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # 報錯:StopIteration: 超過yield的所有元素
              
            
          

next()函數(shù)每次執(zhí)行時,都會繼續(xù)執(zhí)行掛起的生成器函數(shù),直到執(zhí)行完畢。

生成器的這種特點被稱為"延遲計算"或"惰性求值(Lazy evaluation)",可以有效的節(jié)省內(nèi)存。惰性求值實際上是體現(xiàn)了協(xié)同程序的思想。

雖然生成器的這種行為類似于迭代器,但兩者有較大差別,迭代器不具備這種執(zhí)行-暫停-再執(zhí)行-再暫停的特性,所以迭代器不具有延遲計算,沒有協(xié)同程序的思想。

使用延遲計算后,可以極大的節(jié)省內(nèi)存,比如對大文件進行讀取操作時,可以用下列生成器方法:

            
              
                ## 讀取大文件的生成器方法:
              
              
                def
              
              
                load_big_file
              
              
                (
              
              file_path
              
                )
              
              
                :
              
              
    BLOCK_SIZE 
              
                =
              
              
                1024
              
              
                with
              
              
                open
              
              
                (
              
              file_path
              
                ,
              
              
                'rb'
              
              
                )
              
              
                as
              
               f
              
                :
              
              
                while
              
              
                True
              
              
                :
              
              
            block 
              
                =
              
               f
              
                .
              
              read
              
                (
              
              BLOCK_SIZE
              
                )
              
              
                if
              
               block
              
                :
              
              
                yield
              
               block 
              
                # 一次只加載一個block到內(nèi)存中,避免MemoryError
              
              
                else
              
              
                :
              
              
                return
              
            
          

生成器除了用next()函數(shù)來處理之外,還可以用close()來隨時退出生成器。如下代碼:

            
              
                ## 使用close()可以隨時退出生成器
              
              
square_five
              
                =
              
              squares
              
                (
              
              
                5
              
              
                )
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # 0
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # 1
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # 4
              
              
square_five
              
                .
              
              close
              
                (
              
              
                )
              
              
                # 退出生成器
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # Error: StopIteration:
              
              
                print
              
              
                (
              
              
                next
              
              
                (
              
              square_five
              
                )
              
              
                )
              
              
                # Error: StopIteration:
              
            
          

2. 生成器表達式

從形式上來看,生成器表達式和列表推導(dǎo)式很像,僅僅是將列表推導(dǎo)式中的[]替換為(),但是兩者差別挺大,生成器表達式可以說組合了迭代功能和列表解析功能。

生成器表達式可以認為是一種特殊的生成器函數(shù),類似于lambda表達式和普通函數(shù)。但是和生成器一樣,生成器表達式也是返回生成器generator對象,一次只返回一個值。

            
              
                # 上面的squares函數(shù)可以改寫為:
              
              
                # 列表推導(dǎo)式的寫法是:
              
              
squares_list
              
                =
              
              
                [
              
              i
              
                *
              
              i 
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                5
              
              
                )
              
              
                ]
              
              
                # 一次性返回整個list
              
              
                print
              
              
                (
              
              
                '列表推導(dǎo)式:'
              
              
                ,
              
              squares_list
              
                )
              
              
                # 列表推導(dǎo)式: [0, 1, 4, 9, 16]
              
              
                # 生成器表達式:
              
              
squares2
              
                =
              
              
                (
              
              i
              
                *
              
              i 
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                5
              
              
                )
              
              
                )
              
              
                # 生成器表達式一次返回一個值
              
              
                print
              
              
                (
              
              
                '生成器表達式:'
              
              
                ,
              
              squares2
              
                )
              
              
                # 生成器表達式: 
                
                  
                    print
                  
                  
                    (
                  
                  
                    next
                  
                  
                    (
                  
                  squares2
                  
                    )
                  
                  
                    )
                  
                  
                    # 0
                  
                  
                    print
                  
                  
                    (
                  
                  
                    next
                  
                  
                    (
                  
                  squares2
                  
                    )
                  
                  
                    )
                  
                  
                    # 1
                  
                  
                    print
                  
                  
                    (
                  
                  
                    next
                  
                  
                    (
                  
                  squares2
                  
                    )
                  
                  
                    )
                  
                  
                    # 4
                  
                
              
            
          

生成器表達式是一種特殊的生成器,所以它也有生成器的特性,可以使用for循環(huán)來獲取元素值,for循環(huán)內(nèi)部自動調(diào)用了next()函數(shù)來執(zhí)行。

            
              
                # generator對象可以直接用for來獲取所有元素值
              
              
squares2
              
                =
              
              
                (
              
              i
              
                *
              
              i 
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                5
              
              
                )
              
              
                )
              
              
                # 生成器表達式就是一個generator對象
              
              
                for
              
               i 
              
                in
              
               squares2
              
                :
              
              
                print
              
              
                (
              
              
                'i: '
              
              
                ,
              
              i
              
                )
              
              
                # 上面可以簡寫為:
              
              
                [
              
              
                print
              
              
                (
              
              
                'i: '
              
              
                ,
              
              i
              
                )
              
              
                for
              
               i 
              
                in
              
              
                (
              
              i
              
                *
              
              i 
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                5
              
              
                )
              
              
                )
              
              
                ]
              
            
          

生成器表達式如果作為某個函數(shù)的參數(shù),則可以省略掉(),直接使用即可,eg:

            
              
                ## 如果生成器表達式整個作為某個函數(shù)的參數(shù),可以省略掉()
              
              
max_value
              
                =
              
              
                max
              
              
                (
              
              i
              
                *
              
              i 
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                5
              
              
                )
              
              
                )
              
              
                # 計算生成器的所有元素中的最大值
              
              
                print
              
              
                (
              
              max_value
              
                )
              
              
                # 16
              
            
          

首次發(fā)表于: 微信公眾號:科技老丁哥,ID: TechDing,敬請關(guān)注。

本文所有代碼都已經(jīng)上傳到我的github,歡迎下載

參考資料:

  1. 《流暢的Python》,Luciano Ramalho (作者) 安道 , 吳珂 (譯者)。

更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久精品欧美一区二区三区不卡 | 欧美一级特黄aaaaaa在线看首页 | 免费jizz在线播放视频 | av国产精品 | 91中文字幕在线观看 | 亚洲成人二区 | 亚洲精品免费在线观看 | 91婷婷韩国欧美一区二区 | 亚洲视频在线观看一区 | 亚洲精品自拍 | 欧美在线观看一区 | 奶子吧naiziba.cc免费午夜片在线观看 | 91久久艹 | 成人国产精品免费 | 久久久久免费观看 | 国产在线精品一区二区三区 | 嫩草www | 一区二区欧美视频 | 亚洲乱人伦在线 | 波多野结衣手机视频一区 | 97精品国产综合久久 | 成人福利视频网 | 久久久久久免费一区二区三区 | 国产欧美日韩精品一区 | 狠狠天天 | 男女做性无遮挡免费视频 | 99热欧美| 久久久国产精品x99av | 欧美 日本 国产 | 成年人免费网站视频 | 天天操网 | 色爱av| 福利在线播放 | 国产成人精品在线 | 日韩久久精品电影 | 日韩第3页| 懂色中文一区二区三区在线视频 | 成人黄色在线观看视频 | www.黄色网.com| 国产精品3区 | 在线播放高清视频www |