Python 使用收益率(列表)与收益率

Python 使用收益率(列表)与收益率,python,python-3.x,generator,Python,Python 3.x,Generator,我创建了两个枚举方法,一个返回列表,另一个返回产量/生成器: def enum_list(sequence, start=0): lst = [] num = start for sequence_item in sequence: lst.append((num, sequence_item)) num += 1 return lst def enum_generator(sequence, start=0): num

我创建了两个枚举方法,一个返回列表,另一个返回产量/生成器:

def enum_list(sequence, start=0):
    lst = []
    num = start
    for sequence_item in sequence:
        lst.append((num, sequence_item))
        num += 1
    return lst


def enum_generator(sequence, start=0):
    num = start
    for sequence_item in sequence:
        yield (num, sequence_item)
        num += 1
关于这一点,有几个问题:

(1) 将列表更改为生成器是否与执行以下操作一样简单:

# build via list
l = list()
for item in items:
    l.append(item)

# build via iterator
# l = list() (1) <== delete this line
for item in items:
    yield item # (2) change l.append(...) to yield ...
#通过列表构建
l=列表()
对于项目中的项目:
l、 追加(项目)
#通过迭代器构建
#l=list()(1)(1)生成器只需将收益率添加到迭代中即可创建


(2) 是的,用于惰性评估。但生成器也用于创建堆栈和队列,因为它们只能迭代一次。上下文管理器中也可以利用此属性,通过生成上下文。

您案例中的另一个区别是,由于列表是在使用前创建的,并且生成器在每次下一次调用时都进行求值,因此生成器函数可以检查上下文,并根据外部条件得出每个生成的不同结果,随时间而变化

考虑伪代码:

def alloted_time():
    while True:
         if len(global_queue)>10:
            yield 5
         else:
            yield 10

如果队列很大,给下一个人分配5分钟,其他10分钟。

还可以看出,很难理解你在问什么。你说的“将数组(你是指列表?)更改为生成器”是什么意思?@juanpa.arrivillaga更新了问题。同样,我也不确定你在问什么。生成器是一种语言结构,允许您轻松编写迭代器,其方式通常比使用完整迭代器协议更容易理解/更具表达力。列表和生成器是两种不同的东西。列表是容器,生成器是迭代器。@juanpa.arrivillaga真的谢谢你,我又犯了同样的错误,混淆了迭代器和生成器。@juanpa.arrivillaga不太清楚你为什么这么说。生成器类也是生成器,定义了
\uu iter\uuuuuu
\uuuu next\uuuuuu
后,它不需要
屈服
就可以成为生成器。例如,@blhsing没有“生成器类”这样的东西。类可以实现迭代器协议,在这种情况下,它可以是迭代器。所有生成器都是迭代器,并非所有迭代器都是生成器。如果它不使用yield,那么它就不是生成器(除非它是生成器表达式)。因此,您可以自己尝试,使用链接答案中的示例迭代器和导入类型;print(isinstance(Fib(),types.GeneratorType))
@juanpa.arrivillaga刚刚查阅了发电机的官方词汇表。你说得对,生成器的精确定义是一个生成函数。我猜人们只是简单地把iterable类和generator混为一谈,以至于它们实际上可以互换使用,这一点可以从短语“generator类”的许多用法中看出,到目前为止没有任何更正。因此,感谢您指出并澄清它。:-)@此外,理解iterable对象和迭代器对象之间的区别很重要。另一件经常被误解/掩盖的事情。我发誓我不仅仅是个书呆子,这其实很重要。至少,它会让你在面试中看起来很好:)为了使它成为一个有用的生成器,你可能需要一个
,而True:
围绕整个事情。否则,无论你使用哪种代码路径,只要一个
yield
,这基本上只是一个不方便使用的函数。@ShadowRanger当然!我觉得我错过了什么,谢谢。