中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python迭代器生成器

發布時間:2020-07-07 03:36:58 來源:網絡 閱讀:187 作者:liangruifeng 欄目:開發技術

  在學習python數據結構的過程中,可迭代對象,迭代器,生成器這些概念參雜在一起,難免讓初學者一頭霧水,今天就來捋捋這些概覽。

可迭代對象(iterable)

  什么是可迭代對象,通俗的講就是可以直接通過for循環遍歷的對象就可稱為可迭代對象Iterable,可以使用isinstance()判斷一個對象是否是Iterable對象:

>>>from collections import Iterable
>>>isinstance([], Iterable)
True
>>>isinstance({}, Iterable)
True
>>>isinstance('123', Iterable)
True
>>>isinstance(123, Iterable)
False

可迭代對象并不指某種具體的數據類型,list, dict, set, str都是迭代對象,再比如打開狀態的files,sockets也是可迭代對象,可迭代對象是指代對象的一種屬性,代表該對象是可迭代的。可迭代對象實現了__iter__方法,該方法返回一個迭代器對象。

迭代器(iterator)

  任何實現了__iter__和__next__方法的對象都是迭代器(python2是實現__iter__和next方法),__iter__返回迭代器自身,__next__返回容器中的下一個值,如果容器中沒有更多元素了,則拋出StopIteration異常。可以使用isinstance()判斷一個對象是否是Iterator對象:

>>>from collections import Iterator
>>>isinstance([], Iterator)
False
>>>isinstance({}, Iterator)
False
>>>isinstance('123', Iterator)
False
>>>isinstance((x for x in range(10)), Iterator)
True

其中(x for x in range(10))是生成器表達式,它返回的是一個生成器對象,不同于列表生成式[x for x in range(10)]返回一個list對象。生成器對象都是迭代器對象,但list, dict, str雖然是可迭代對象,但不是迭代器對象,可以使用iter()將list, dict, str等可迭代對象變成迭代器對象。

>>>isinstance(iter([]), Iterator)
True
>>>isinstance(iter('123'), Iterator)
True

python的迭代器對象表示一個數據流,可以將這個數據流看作一個有序序列,但我們并不知道序列的長度,只能不斷通過調用next()函數實現按需計算下一個數據,因此迭代器的計算是惰性的,只有在需要返回下一個數據時它才計算,迭代器的這種特性可以大大減少內存的開銷,迭代器對象甚至可以表示一個無限大的數據流,而讓list, dict或者str存儲一個無限大的數據流是不可能的。

下面我們通過迭代器來實現斐波那契數列:

from collections import Iterable
from collections import Iterator

class Fib:
    def __init__(self, max):
        self.n, self.max = 0, max
        self.a, self.b = 0, 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.n < self.max:
            self.n += 1
            self.a, self.b = self.b, self.a + self.b
            return self.a
        else:
            raise StopIteration

if __name__ == '__main__':
    fib = Fib(10)
    print(isinstance(fib, Iterable)) # True
    print(isinstance(fib, Iterator)) # True
    print([e for e in fib]) # [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

  Fib既是一個可迭代對象(因為它實現了__iter__方法),又是一個迭代器(因為實現了__next__方法)。實例變量a和b用于維護迭代器內部的狀態。每次調用next()方法的時候做兩件事:
為下一次調用next()方法修改狀態,為當前這次調用生成返回結果。

迭代器就像一個懶加載的工廠,等到有人需要的時候才給它生成值返回,沒調用的時候就處于休眠狀態等待下一次調用。

生成器(generator)

  生成器是一種特殊的迭代器,不過這種迭代器更加優雅。它不需要再像上面的類一樣寫__iter__()和__next__()方法了,只需要一個yiled關鍵字。

用生成器來實現斐波那契數列的例子是:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        n = n + 1
        a, b = b, b + a
        yield a

f = fib(10)
print(f) # <generator object fib at 0x10d8cf888>
print([e for e in f])   # [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

fib函數中的yield關鍵字,將該函數變成了一個生成器,當執行f=fib(10)返回的是一個生成器對象,此時函數中的代碼并不會執行,只有顯示或隱示地調用next的時候才會真正執行里面的代碼,在每次調用next()方法時,遇到yield語句返回值并中斷,再次執行時從上次返回的yield語句處繼續執行。
生成器是python非常強大的特性,相比其他容器對象它更加節省內存,同時使用更少的代碼,使你的代碼更加的優雅,凡事以下結構都可以通過生成器重構:

def fun():
    result = []
    for ... in ...:
        result.append(x)
    return result

def fun_gen():
    for ... in ...:
        yield x
總結
  1. 可迭代對象實現了__iter__方法,該方法返回一個迭代器對象。
  2. 迭代器持有一個內部狀態的字段,用于記錄下次迭代返回值,它實現了__next__和__iter__方法,迭代器不會一次性把所有元素加載到內存,而是需要的時候才生成返回結果。
  3. 生成器是一種特殊的迭代器,它的返回值不是通過return而是用yield。
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

祁连县| 五常市| 洪江市| 涿鹿县| 修武县| 开江县| 永善县| 三台县| 聂荣县| 绵竹市| 遂昌县| 无极县| 信宜市| 长岛县| 宝清县| 天祝| 泰来县| 商洛市| 鄂州市| 盖州市| 涞源县| 大方县| 万全县| 海门市| 焦作市| 青川县| 东莞市| 微山县| 虹口区| 铁岭市| 怀安县| 镇雄县| 柳江县| 西华县| 娄烦县| 天祝| 东源县| 平原县| 江西省| 侯马市| 保山市|