簡體   English   中英

與 Python 中的生成器相比,非生成器迭代器有什么優勢嗎?

[英]Are there any advantages of non-generator iterators over generators in Python?

在下面的代碼中, i1是一個迭代器。

def sq(x):

    y = []

    for i in x:
        y.append(i**2)

    return y

l1 = range(5)
s1 = sq(l1)
i1 = iter(s1)

我可以為相同的平方運算編寫一個生成器。 在下面的代碼中, g1是一個生成器。

def sqg(x):

    for i in x:

        yield i**2

g1 = sqg(l1)

我知道生成器使用更少的代碼並且更易於讀寫。 我知道生成器也運行得更快,因為它們保持本地狀態。

使用i1優於g1有什么優勢嗎?

當您調用sq(l1)時,在sq內部會填充一個列表y 這會消耗 memory,其大小與x的大小成正比,一旦耗盡。

在第二種情況下,當您調用sqg(l1)時, sqg沒有任何用於存儲結果的內部列表。 它直接產生計算值,使得 memory 消耗常數並且與x的大小無關。

至於非生成器迭代器相對於生成器的優勢,我認為沒有性能優勢,但可能存在結構優勢。 生成器(一種像您提到的迭代器)被定義為通過調用 function 返回的迭代器,其中包含yield語句。 這意味着您不能向代表生成器的 object 添加任何可調用的其他方法,因為這種特殊類型的迭代器是隱式提供給您的。

另一方面,迭代器有一個更寬松的定義:一個 object 帶有一個__next__方法和一個返回self__iter__方法。 您可以創建一個 class Squares遵循前面的迭代器標准,並且為了獲得該迭代器的實例,您必須顯式實例化Squares 因為您可以控制返回給您的迭代器的屬性,所以您可以添加返回該迭代器的內部 state 的實例方法,這些方法不是通過__next__表示的,而使用生成器時,您會被鎖定到隱式提供給您的生成器 object 中。 通常,生成器會完成這項工作,但有時您需要使用非生成器迭代器來獲得超越__next__提供的功能所需的控制。

在這種特定情況下,我認為您不需要通過使用非生成器迭代器給予您顯式控制,因此使用生成器會更好。

創建列表s1優於生成器的優點 - 它具有定義的長度,您可以對其進行索引和切片,並且可以多次迭代它而無需重新創建它。 不過,也許您不會將這些視為非生成器迭代器的優勢。

另一個區別是,基於列表的迭代器涉及預先完成所有工作,然后緩存結果,而生成器一次完成工作。 如果處理任務是資源密集型的,那么列表方法會在生成列表時導致初始暫停,然后運行速度更快(因為您只需從 memory 檢索結果;還要考慮結果可以緩存在文件中, 例如)。 生成器方法不會有初始暫停,但會在生成每個結果時運行得更慢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM