两个连续的 yield 语句如何在 python 中工作?

新手上路,请多包涵

我在 pymotw.com 的合并和拆分部分偶然发现了这段代码。

 from itertools import *

def make_iterables_to_chain():
    yield [1, 2, 3]
    yield ['a', 'b', 'c']

for i in chain.from_iterable(make_iterables_to_chain()):
    print(i, end=' ')
print()

我不明白 make_iterables_to_chain() 是如何工作的。它包含两个 yield 语句,它是如何工作的?我知道生成器是如何工作的,但那里只有一个 yield 语句。

请帮忙!

原文由 unnobtainium 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 980
2 个回答

与单个 yield 工作方式相同。

您可以在生成器中拥有任意数量的 yield s,当调用 __next__ 时,它将执行直到遇到下一个 yield。然后,您返回生成的表达式,生成器暂停,直到再次调用 __next__ 方法。

在生成器上运行几个 next 调用以查看:

 >>> g = make_iterables_to_chain()  # get generator
>>> next(g) # start generator, go to first yield, get result
[1, 2, 3]
>>> next(g) # resume generator, go to second yield, get result
['a', 'b', 'c']
>>> # next(g) raises Exception since no more yields are found

原文由 Dimitris Fasarakis Hilliard 发布,翻译遵循 CC BY-SA 3.0 许可协议

生成器有效地允许函数返回 多次。每执行一次 yield 语句,返回值给调用者,调用者可以继续函数的执行。

通常,它们在 for 循环中用作可迭代对象。

以下函数将可迭代对象中的每个元素递增一个数量:

 def inc_each(nums, inc):
    for i in nums:
        yield i + inc

这是一个用法示例:

 gen = inc_each([1, 2, 3, 4], 100)
print(list(gen)) # [101, 102, 103, 104]

list 在这里用于将任意可迭代对象(在本例中为生成器)转换为列表。

您描述的函数执行两个 yield 语句:

 def make_iterables_to_chain():
    yield [1, 2, 3]
    yield ['a', 'b', 'c']

如果调用它,它会返回一个生成器,如果对其进行迭代,则会生成列表 [1, 2, 3]['a', 'b', 'c']

 gen = make_iterables_to_chain()
print(list(gen)) # [[1, 2, 3], ['a', 'b', 'c']]

itertools.chain.from_iterable 将获取一个(可能是无限的)可迭代对象并“展平”它,返回一个(可能是无限的)可迭代对象作为结果。

这是一种可以实现的方法:

 def from_iterable(iterables):
    for iterable in iterables:
        for i in iterable:
            yield i

原文由 Challenger5 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题