与Python中的生成器相比,非生成器迭代器有什么优势吗? [英] Are there any advantages of non-generator iterators over generators in Python?

查看:168
本文介绍了与Python中的生成器相比,非生成器迭代器有什么优势吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,i1是一个迭代器.

In the code below, i1 is an iterator.

def sq(x):

    y = []

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

    return y

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

我可以为相同的平方运算编写一个生成器.在下面的代码中,g1是生成器.

I can write a generator for the same squaring operation. In the code below, g1 is a generator.

def sqg(x):

    for i in x:

        yield i**2

g1 = sqg(l1)

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

I know that generators use less code and are simpler to read and write. I know that generators also run faster because they maintain their local states.

g1相比,使用i1有什么优势吗?

Are there any advantages to using i1 over g1?

推荐答案

sq内调用sq(l1)时,将填充列表y.一旦耗尽,就会消耗其大小与x的大小成比例的内存.

When you call sq(l1), inside sq, a list y is populated. This consumes memory whose size is proportional to the size of x once exhausted.

在第二种情况下,当您调用sqg(l1)时,sqg没有用于存储结果的任何内部列表.它直接产生计算值,使它消耗的内存恒定不变,并且与x的大小无关.

In the second case, when you call sqg(l1), sqg does not have any internal list used to store the results. It directly yields computed values, making the memory it consumes constant and independent of the size of x once exhausted.

关于非生成器迭代器相对于生成器的优势,我认为不存在性能优势,但是可能存在结构优势.生成器(如您所指出的一种迭代器类型)定义为通过调用其中带有yield语句的函数返回的迭代器.这意味着您不能将任何可以调用的其他方法添加到表示生成器的对象上,因为这种特殊类型的迭代器是隐式提供给您的.

As for advantages of non-generator iterators over generators, I don't believe there are performance advantages, but there could be structural advantages. A generator (a type of iterator like you noted) is defined to be an iterator returned by calling a function with yield statements inside of it. That means that you cannot add any additional methods that can be called to the object representing the generator, because this special type of iterator is given to you implicitly.

另一方面,迭代器的定义较为宽松:具有__next__方法和__iter__方法返回self的对象.您可以使类Squares遵循先前的迭代器标准,并且为了使该迭代器具有实例,必须显式实例化Squares. 因为您可以控制返回给您的迭代器的属性,因此您可以添加实例方法,以返回该迭代器的内部状态,而这些实例状态不是通过__next__表示的,而使用生成器则被锁定了隐式提供给您的生成器对象.通常,生成器会完成这项工作,但是有时您需要使用非生成器迭代器来获得所需的控件,而该控件需要通过__next__提供的功能.

On the other hand, an iterator has a looser definition: an object with a __next__ method and an __iter__ method returning self. You could make a class Squares that follows the previous criteria for an iterator, and in order to get an instance to this iterator, you would have to explicitly instantiate Squares. Because you have control over the attributes of the iterator returned to you, you could add instance methods returning internal state of that iterator that aren't expressed through __next__, whereas with a generator you're locked into the generator object provided to you implicitly. Often a generator will do the job, but sometimes you need to use a non-generator iterator to get the control you need past the functionality provided by __next__.

在这种特定情况下,我认为您不需要使用非生成器迭代器来提供显式控制,因此使用生成器会更好.

In this specific case, I don't believe you need the explicit control given to you by using a non-generator iterator, so it would be better to use a generator.

这篇关于与Python中的生成器相比,非生成器迭代器有什么优势吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆