gpt4 book ai didi

python - 内部包含 `yield` 的列表理解和生成器理解之间的区别

转载 作者:太空狗 更新时间:2023-10-29 18:09:04 25 4
gpt4 key购买 nike

列表推导式和带有 yield 的生成器推导式之间有什么区别?两者都返回一个生成器对象(分别为 listcompgenexpr),但在全面评估后,后者添加了看起来相当多余的 None

>>> list([(yield from a) for a in zip("abcde", itertools.cycle("12"))])
['a', '1', 'b', '2', 'c', '1', 'd', '2', 'e', '1']

>>> list(((yield from a) for a in zip("abcde", itertools.cycle("12"))))
['a', '1', None, 'b', '2', None, 'c', '1', None, 'd', '2', None, 'e', '1', None]

怎么会?科学解释是什么?

最佳答案

TLDR:生成器表达式使用隐式 yield ,返回 None来自 yield from表达。

这里实际上有两个行为不同。你的列表理解实际上被扔掉了......

  • 再次清晰

如果将表达式转换为等价函数,理解这一点就最容易了。为了清楚起见,让我们把它写出来:

listcomp = [<expr> for a in b]
def listfunc():
result = []
for a in b:
result.append(<expr>)
return result

gencomp = (<expr> for a in b)
def genfunc():
for a in b:
yield <expr>

要复制初始表达式,关键是替换<expr>(yield from a) .这是一个简单的文本替换:

def listfunc():
result = []
for a in b:
result.append((yield from a))
return result

def genfunc():
for a in b:
yield (yield from a)

b = ((1,), (2,)) , 我们期望输出 1, 2 .事实上,两者都复制了各自表达/理解形式的输出。

如解释elsewhere , yield (yield from a)应该让你怀疑。然而,result.append((yield from a))应该让你畏缩......

  • 给出答案

让我们先看看生成器。另一个重写使得正在发生的事情一目了然:

def genfunc():
for a in b:
result = (yield from a)
yield result

为了使其有效,result必须有一个值 - 即 None .生成器 yield (yield from a)表达式,而是它的结果。你只得到a的内容作为计算表达式的副作用。

  • 回到问题

如果您检查“列表理解”的类型,它不是 list - 它是 generator . <listcomp>只是它的名字。是的,那不是月球,那是一个功能齐全的发电机。

请记住我们的转换是如何将 yield from在一个函数里面?是的,这就是你定义生成器的方式!这是我们的函数版本,这次是 print洒在上面:

def listfunc():
result = []
for a in b:
result.append((yield from a))
print(result[-1])
print(result)
return result

正在评估 list(listfunc()) 打印 None , None (来自 append )和 [None, None] (来自 result )和产量 1, 2 .您的实际列表包含那些 None也潜入了发电机!然而,它被扔掉了,结果又只是一个副作用。这是实际发生的事情:

  • 生成器是在评估列表理解/listfunc 时创建的.
  • 将其提供给 list遍历它...
    • yield from a产生 a 的值至 list 并返回 None理解/listfunc
    • None存储在结果列表中
  • 在迭代结束时...

    • return提高 StopIteration值为 [None, None]
    • list构造函数忽略它并丢弃该值
  • 这个故事的寓意

不要使用 yield from领悟之内。它并没有按照您的想法行事。

关于python - 内部包含 `yield` 的列表理解和生成器理解之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35033985/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com