欧美三区_成人在线免费观看视频_欧美极品少妇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條評論
主站蜘蛛池模板: 久久网精品视频 | 一区二区三区四区五区中文字幕 | 夜婷婷 | 99午夜高清在线视频在观看 | 超碰3| 国产精品99爱免费视频 | 丝袜美腿一区二区三区动态图 | 国产精品成人一区二区 | 国产vr一区二区在线观看 | 超级碰在线视频 | 性欧美一区 | 天天操bb | 97在线观看视频 | 欧美视频区 | 欧美三级在线 | 亚洲色欲色欲www | 91福利免费观看 | 99久久免费看精品 | 亚洲一二三 | 日本二本三本二区 | 精品久久一区二区三区 | 日韩欧美一区二区三区免费观看 | 久久精品视频一区二区 | 精品一区二区三区四区五区六区 | 99久久亚洲精品日本无码 | 久九九精品免费视频 | 欧美一级www片免费观看 | 色综合久久88色综合天天 | 亚洲欧美日本在线观看 | 91 在线| 一区二区久久 | av影音 | 精品国产理论在线观看不卡 | 亚洲精品九九 | 久久福利一区 | 日韩中文一区二区三区 | 欧美日韩在线视频观看 | 天天操,夜夜操 | 99爱国产| 免费的色网站 | 九九热精品视频在线播放 |