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

Python 的可迭代對象、迭代器和生成器

系統 1672 0

迭代器和可迭代對象

由for循環的內部原理說起

            
              list01 
              
                =
              
              
                [
              
              
                2
              
              
                ,
              
              
                434
              
              
                ,
              
              
                5
              
              
                ,
              
              
                6
              
              
                ,
              
              
                8
              
              
                ]
              
              
                for
              
               item 
              
                in
              
               list01
              
                :
              
              
                print
              
              
                (
              
              item
              
                )
              
            
          

大家有沒有想過list類型對象為什么可以被for循環呢?

            
              能夠被for循環的條件是:它是可迭代對象(iterable)。

            
          

那么什么是 可迭代對象 呢?
參考一下內置函數item()的官方說明文檔:

iter(object[, sentinel])
返回一個 iterator對象。根據是否存在第二個實參,第一個實參的解釋是非常不同的。如果沒有第二個實參,object 必須是支持迭代協議(有 iter () 方法)的集合對象,或必須支持序列協議(有 getitem () 方法,且數字參數從 0 開始)。如果它不支持這些協議,會觸發 TypeError。如果有第二個實參 sentinel,那么 object 必須是可調用的對象。這種情況下生成的迭代器,每次迭代調用它的 next () 方法時都會不帶實參地調用 object;如果返回的結果是 sentinel 則觸發 StopIteration,否則返回調用結果。

由此我們可以明確知道什么是可迭代的對象:即對象實現了能返回迭代器的 iter 方法,或對象實現了 getitem 方法,而且其參數是從零開始的索引。(兩者都實現也行)
一文讀懂Python可迭代對象、迭代器和生成器

判斷一個對象是否是可迭代對象:

            
              
                # 看__iter__方法 或 __getitem__方法是否在__dir__字典里(用dir()內置方法),若存在就說明
              
              
                # 它是一個可迭代對象
              
              
                >>
              
              
                >
              
              
                '__iter__'
              
              
                in
              
              
                dir
              
              
                (
              
              
                [
              
              
                ]
              
              
                )
              
              
                True
              
              
                >>
              
              
                >
              
              
                '__getitem__'
              
              
                in
              
              
                dir
              
              
                (
              
              
                [
              
              
                ]
              
              
                )
              
              
                #還要進一步看其數字參數是否從 0 開始
              
              
                True
              
              
                >>
              
              
                >
              
            
          

情況一:實現了能返回迭代器的__iter__方法(迭代器是具有 __next__() 方法的對象)。

            
              
                class
              
              
                SkillIterator
              
              
                :
              
              
                """
        迭代器
    """
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
               target
              
                )
              
              
                :
              
              
        self
              
                .
              
              target 
              
                =
              
               target
        self
              
                .
              
              index 
              
                =
              
              
                0
              
              
                def
              
              
                __next__
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                # 如果索引越界 則拋出StopIteration異常
              
              
                if
              
               self
              
                .
              
              index 
              
                >
              
              
                len
              
              
                (
              
              self
              
                .
              
              target
              
                )
              
              
                -
              
              
                1
              
              
                :
              
              
                raise
              
               StopIteration
        
              
                # 返回下一個元素
              
              
        item 
              
                =
              
               self
              
                .
              
              target
              
                [
              
              self
              
                .
              
              index
              
                ]
              
              
        self
              
                .
              
              index 
              
                +=
              
              
                1
              
              
                return
              
               item


              
                class
              
              
                SkillManager
              
              
                :
              
              
                """
        可迭代對象
    """
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
               skills
              
                )
              
              
                :
              
              
        self
              
                .
              
              skills 
              
                =
              
               skills

    
              
                def
              
              
                __iter__
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                # 創建迭代器對象  傳遞 需要迭代的數據
              
              
                return
              
               SkillIterator
              
                (
              
              self
              
                .
              
              skills
              
                )
              
            
          

情況二:對象實現了 getitem 方法,而且其參數是從零開始的索引,python解釋器會創建一個迭代器并嘗試按順序(從索引 0 開始)獲取元素。

            
              
                class
              
              
                Eter_a
              
              
                :
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
              text
              
                )
              
              
                :
              
              
        self
              
                .
              
              sub_text
              
                =
              
              text
              
                .
              
              split
              
                (
              
              
                " "
              
              
                )
              
              
                def
              
              
                __getitem__
              
              
                (
              
              self
              
                ,
              
               index
              
                )
              
              
                :
              
              
                return
              
               self
              
                .
              
              sub_text
              
                [
              
              index
              
                ]
              
              

ob_a
              
                =
              
              Eter_a
              
                (
              
              
                "Hello world!"
              
              
                )
              
              
                for
              
               i 
              
                in
              
               ob_a
              
                :
              
              
                print
              
              
                (
              
              i
              
                )
              
            
          

一般我們不用getitem去實現一個迭代器,所以重點還是放在 __iter__上好了。
補充一下:標準迭代器里面大部分都同時實現了__next__和__iter__方法。所以有人這樣說:

            
              內部含有'__iter__'并且含有"__next__"方法的對象,就是迭代器

            
          

for循環內部原理

實際執行情況如下圖:
Python 的可迭代對象、迭代器和生成器_第1張圖片
1)調用可迭代對象的__inter__方法返回一個迭代器對象(iterator)
2)不斷調用迭代器的__next__方法返回元素
3)知道迭代完成后,處理StopIteration異常

根據以上條件,我們使用while來模擬一下for循環:

            
              
                # 1. 獲取迭代器對象
              
              
list01 
              
                =
              
              
                [
              
              
                2
              
              
                ,
              
              
                434
              
              
                ,
              
              
                5
              
              
                ,
              
              
                6
              
              
                ,
              
              
                8
              
              
                ]
              
              
iterator 
              
                =
              
               list01
              
                .
              
              __iter__
              
                (
              
              
                )
              
              
                #(1)先調用__iter__方法獲取一個迭代器
              
              
                while
              
              
                True
              
              
                :
              
              
                try
              
              
                :
              
              
        item 
              
                =
              
               iterator
              
                .
              
              __next__
              
                (
              
              
                )
              
              
                # (2)不斷調用迭代器的__next__方法
              
              
                print
              
              
                (
              
              item
              
                )
              
              
                except
              
               StopIteration
              
                :
              
              
                #(3)直到捕獲StopIteration異常停止迭代
              
              
                break
              
              
                # (4)跳出循環體
              
            
          

生成器generator

(首先它是一個函數,特殊之處在于函數使用yield返回,這樣在調用此函數時會返回一個生成器對象,這是一個函數到對象的神奇過程,體現了一種惰性返回的思維(即用到才返回,不用不返回,而不是管你用不用哪怕只用一部分也一次性全部返回return)。生成器是迭代器的一種,明白了吧,想更深入理解就往下看)
生成器及其作用
python 生成器和迭代器有這篇就夠了

通過列表生成式,我們可以直接創建一個列表,但是,受到內存限制,列表容量肯定是有限的,而且創建一個包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那后面絕大多數元素占用的空間都白白浪費了。

所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出后續的元素呢?這樣就不必創建完整的list,從而節省大量的空間,在Python中,這種一邊循環一邊計算的機制,稱為生成器:generator

生成器是一個特殊的程序,可以被用作控制循環的迭代行為,python中生成器是迭代器的一種,使用yield返回值函數,每次調用yield會暫停,而可以使用next()函數和send()函數恢復生成器。

生成器類似于返回值為數組的一個函數,這個函數可以接受參數,可以被調用,但是,不同于一般的函數會一次性返回包括了所有數值的數組,生成器一次只能產生一個值,這樣消耗的內存數量將大大減小,而且允許調用函數可以很快的處理前幾個返回值,因此生成器看起來像是一個函數,但是表現得卻像是迭代器。

生成器:generator

1.定義:能夠動態(循環一次計算一次返回一次)提供數據的可迭代對象。
2.作用:在循環過程中,按照某種算法推算數據,不必創建容器存儲完整的結果,從而節省內存空間。數據量越大,優勢越明顯。
3.以上作用也稱之為延遲操作或惰性操作,通俗的講就是在需要的時候才計算結果,而不是一次構建出所有結果。

生成器函數

1.定義: 含有yield語句的函數,返回值為生成器對象
2. 創建語法

            
              
                def
              
               函數名
              
                (
              
              
                )
              
              
                :
              
                yield
              
               數據
	…

            
          

– 調用:

            
              
                for
              
               變量名 
              
                in
              
               函數名
              
                (
              
              
                )
              
              
                :
              
              
		  語句

            
          

3.說明:

  • 調用生成器函數將返回一個生成器對象,不執行函數體。
  • yield翻譯為”產生”或”生成”

4.執行過程:
(1) 調用生成器函數會自動創建迭代器對象。
(2) 調用迭代器對象的__next__()方法時才執行生成器函數。
(3) 每次執行到yield語句時返回數據,暫時離開。
(4) 待下次調用__next__()方法時繼續從離開處繼續執行。

5.原理:生成迭代器對象的大致規則如下

  • 將yield關鍵字以前的代碼放在next方法中。
  • 將yield關鍵字后面的數據作為next方法的返回值。
    (qz理解:或者說當內部調用next方法時,會跳到yield關鍵字之前的代碼繼續執行,并且將yield關鍵字后面的數據作為next方法的返回值,因為調試的話執行next會跳到yield關鍵字之前的代碼。)

內置生成器

1,枚舉函數enumerate
1).語法:

            
              
                for
              
               變量 
              
                in
              
              
                enumerate
              
              
                (
              
              可迭代對象
              
                )
              
              
                :
              
              
     語句


              
                for
              
               索引
              
                ,
              
               元素
              
                in
              
              
                enumerate
              
              
                (
              
              可迭代對象
              
                )
              
              
                :
              
              
    語句

            
          

2).作用:遍歷可迭代對象時,可以將索引與元素組合為一個元組。

2,zip函數
1).語法:

            
              
                for
              
               item 
              
                in
              
              
                zip
              
              
                (
              
              可迭代對象
              
                1
              
              
                ,
              
               可迭代對象
              
                2
              
                .
              
              
                )
              
              
                :
              
              
    		語句

            
          

2).作用:將多個可迭代對象中對應的元素組合成一個個元組,生成的元組個數由最小的可迭代對象決定。

生成器表達式

1.定義:用推導式形式創建生成器對象。
2.語法:變量 = ( 表達式 for 變量 in 可迭代對象 [if 真值表達式] )
(注意:可不要誤解是元組推導式,不存在元組推導式,因為元組是不可變序列)

            
              
                >>
              
              
                >
              
              
                (
              
              i 
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                1
              
              
                ,
              
              
                10
              
              
                )
              
              
                )
              
              
                <
              
              generator 
              
                object
              
              
                <
              
              genexpr
              
                >
              
               at 
              
                0x0000023A9DDA7408
              
              
                >
              
              
                >>
              
              
                >
              
              
                [
              
              i 
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                1
              
              
                ,
              
              
                10
              
              
                )
              
              
                ]
              
              
                [
              
              
                1
              
              
                ,
              
              
                2
              
              
                ,
              
              
                3
              
              
                ,
              
              
                4
              
              
                ,
              
              
                5
              
              
                ,
              
              
                6
              
              
                ,
              
              
                7
              
              
                ,
              
              
                8
              
              
                ,
              
              
                9
              
              
                ]
              
              
                >>
              
              
                >
              
            
          

更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久福利青草狠狠午夜 | 国产一区二区精品在线观看 | 天天操天天摸天天爽 | 麻豆av免费观看 | 99这里有精品 | 男女超猛烈啪啦啦的免费视频 | 日本妇人成熟免费不卡片 | 五月综合激情在线 | 日韩精品一区二区三区中文 | 国产女人一区二区 | 欧美妇人| 日韩欧美综合在线二区三区 | 欧美在线一二三区 | 天天搞夜夜操 | 国产亚洲欧美日本一二三本道 | 五月天婷婷缴情五月免费观看 | 中文一区二区 | 九九色影院 | 嫩草影院在线看 | 狠狠操狠狠操 | 日韩免费一区二区 | 亚洲毛片无码专区亚洲A片 日本高清www午色夜黄 | 久久99精品热在线观看15 | 国产97人妻人人做人碰人人爽 | 国产成人理在线观看视频 | 久久久久久国产精品久久 | 欧美videosex性欧美成人 | 欧美又黄又嫩大片a级 | 玖玖玖免费观看视频 | 午夜视频在线免费观看 | 国产成人91 | 日本高清视频www | 日韩精品一区二区三区 | 99je全部都是精品视频在线 | 在线精品国内外视频 | 色综合五月色婷婷开心 | 国产日韩第一页 | 久久新地址| 国产伦精品一区三区视频 | 欧美极品在线观看 | 久久综合婷婷香五月 |