gpt4 book ai didi

python - 使用生成器表达式导致 Python 挂起

转载 作者:太空狗 更新时间:2023-10-30 00:06:25 25 4
gpt4 key购买 nike

我正在试验 2 个模拟 Python 2.x 和 3.x 中内置的 zip 的函数。第一个返回一个列表(如在 Python 2.x 中),第二个是一个生成器函数,它一次返回其结果集的一部分(如在 Python 3.x 中):

def myzip_2x(*seqs):
its = [iter(seq) for seq in seqs]
res = []
while True:
try:
res.append(tuple([next(it) for it in its])) # Or use generator expression?
# res.append(tuple(next(it) for it in its))
except StopIteration:
break
return res

def myzip_3x(*seqs):
its = [iter(seq) for seq in seqs]
while True:
try:
yield tuple([next(it) for it in its]) # Or use generator expression?
# yield tuple(next(it) for it in its)
except StopIteration:
return

print(myzip_2x('abc', 'xyz123'))
print(list(myzip_3x([1, 2, 3, 4, 5], [7, 8, 9])))

这很好用并给出了 zip 内置的预期输出:

[('a', 'x'), ('b', 'y'), ('c', 'z')]
[(1, 7), (2, 8), (3, 9)]

然后我考虑通过删除方括号 [](为什么创建当生成器应该适合 tuple() 预期的可迭代对象时使用推导式的临时列表,对吗?)

但是,这会导致 Python 挂起。如果未使用 Ctrl C 终止执行(在 Windows 上处于空闲状态),它最终将在几分钟后停止并出现(预期的)MemoryError异常。

调试代码(例如使用 PyScripter)显示使用生成器表达式时从未引发 StopIteration 异常。上面对 myzip_2x() 的第一个示例调用不断将空元组添加到 res,而第二个示例调用 myzip_3x() 生成元组(1, 7), (2, 8), (3, 9), (4,) , (5,), (), (), (), ....

我错过了什么吗?

最后一点:如果 its 成为生成器(使用 its = (iter(seq) for seq in seqs))每个函数的行(当在 tuple() 调用中使用列表理解时)。

编辑:

感谢@Blckknght 的解释,你是对的。 This message使用与上面的生成器函数类似的示例提供有关正在发生的事情的更多详细信息。总之,像这样使用生成器表达式仅适用于 Python 3.5+,它需要文件顶部的 from __future__ import generator_stop 语句并将 StopIteration 更改为 上面的 RuntimeError(同样,当使用生成器表达式而不是列表理解时)。

编辑 2:

至于上面的最后一点:如果 its 成为生成器(使用 its = (iter(seq) for seq in seqs))它将只支持一次迭代- 因为生成器是一次性迭代器。因此,它在 while 循环第一次运行时耗尽,在后续循环中仅获得空元组。

最佳答案

您看到的行为是一个错误。它源于这样一个事实,即从生成器中冒出的 StopIteration 异常与正常退出的生成器无法区分。这意味着你不能用 tryexcept 在生成器上包装一个循环并寻找 StopIteration 来让你跳出循环,因为循环逻辑将消耗异常。

PEP 479提出了该问题的修复方法,通过更改语言使生成器中未捕获的 StopIteration 在冒泡之前变成 RuntimeError。这将允许您的代码工作(对您捕获的异常类型进行小的调整)。

PEP 已在 Python 3.5 中实现,但为了保持向后兼容性,仅当您通过将 from __future__ import generator_stop 放在文件顶部来请求时,更改的行为才可用。 Python 3.7 将默认启用新行为(Python 3.6 将默认使用旧行为,但如果出现这种情况可能会发出警告)。

关于python - 使用生成器表达式导致 Python 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32943371/

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