猿问

与 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)

我知道生成器使用更少的代码并且更易于读写。我知道生成器也运行得更快,因为它们保持本地状态。


使用i1over有什么好处g1吗?


扬帆大鱼
浏览 220回答 2
2回答

智慧大石

当您调用sq(l1), inside时,会填充sq一个列表。这会消耗内存,其大小与一旦耗尽y的大小成正比。x在第二种情况下,当您调用 时sqg(l1),sqg没有任何用于存储结果的内部列表。它直接产生计算值,使其消耗的内存恒定且与x一旦耗尽的大小无关。至于非生成器迭代器相对于生成器的优势,我认为没有性能优势,但可能存在结构优势。生成器(一种像您提到的迭代器)被定义为通过调用其中包含yield语句的函数返回的迭代器。这意味着您不能向表示生成器的对象添加任何可调用的附加方法,因为这种特殊类型的迭代器是隐式提供给您的。另一方面,迭代器有一个更宽松的定义:一个带有__next__方法的对象和一个__iter__返回的方法self。您可以创建一个Squares遵循上述迭代器标准的类,并且为了获得该迭代器的实例,您必须显式实例化Squares. 因为您可以控制返回给您的迭代器的属性,所以您可以添加返回该迭代器内部状态的实例方法,这些状态不是通过__next__. 通常,生成器会完成这项工作,但有时您需要使用非生成器迭代器来获得所需的控制,而不是__next__.在这种特定情况下,我认为您不需要通过使用非生成器迭代器给予您显式控制,因此使用生成器会更好。

小唯快跑啊

与生成器相比,创建列表有很多优点s1- 它具有定义的长度,您可以对其进行索引和切片,并且可以多次迭代它而无需重新创建它。不过,也许您不会将这些视为非生成器迭代器的优势。另一个区别是,基于列表的迭代器涉及预先完成所有工作,然后缓存结果,而生成器一次完成工作。如果处理任务是资源密集型的,那么列表方法会在生成列表时导致初始暂停,然后运行速度更快(因为您只需从内存中检索结果;还要考虑结果可以缓存在文件中, 例如)。生成器方法不会有初始暂停,但会在生成每个结果时运行得更慢。
随时随地看视频慕课网APP

相关分类

Python
我要回答