gpt4 book ai didi

python - 为什么这些生成器表达式的行为不同?

转载 作者:太空宇宙 更新时间:2023-11-03 11:01:27 26 4
gpt4 key购买 nike

这两个代码片段的不同之处仅在于列表的构造方式。一个使用 [],另一个使用 list()

这个消耗可迭代对象然后引发一个StopIteration:

>>> try:
... iterable = iter(range(4))
... while True:
... print([next(iterable) for _ in range(2)])
... except StopIteration:
... pass
...
[0, 1]
[2, 3]

这个消耗可迭代对象并永远循环打印空列表。

>>> try:
... iterable = iter(range(4))
... while True:
... print(list(next(iterable) for _ in range(2)))
... except StopIteration:
... pass
...
[0, 1]
[2, 3]
[]
[]
[]
etc.

这种行为的规则是什么?

最佳答案

引用PEP479 , 这表示

The interaction of generators and StopIteration is currently somewhat surprising, and can conceal obscure bugs. An unexpected exception should not result in subtly altered behaviour, but should cause a noisy and easily-debugged traceback. Currently, StopIteration raised accidentally inside a generator function will be interpreted as the end of the iteration by the loop construct driving the generator.

(强调我的)

因此 list 的构造函数迭代传递的生成器表达式,直到引发 StopIteration 错误(通过调用 next(iterable) 而不第二个参数)。另一个例子:

def f():
raise StopIteration # explicitly

def g():
return 'g'

print(list(x() for x in (g, f, g))) # ['g']
print([x() for x in (g, f, g)]) # `f` raises StopIteration

另一方面,* comprehension 在将 StopIteration 传播给调用者时工作方式不同。


链接的PEP提出的行为如下

If a StopIteration is about to bubble out of a generator frame, it is replaced with RuntimeError, which causes the next() call (which invoked the generator) to fail, passing that exception out. From then on it's just like any old exception.

Python 3.5 添加了 generator_stop feature可以使用

启用
from __future__ import generator_stop

此行为将在 Python 3.7 中成为默认行为。

关于python - 为什么这些生成器表达式的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31361182/

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