listcomprehension抛出一个运行时错误

2024-05-19 11:03:54 发布

您现在位置:Python中文网/ 问答频道 /正文

为什么这段代码运行良好并且不抛出异常

def myzip(*args):
    iters = [iter(arg) for arg in args]
    try:
        while True:
            yield tuple([next(it) for it in iters])
    except StopIteration:
        return


for x, y, z in myzip([1, 2], [3, 4], [5, 6]):
    print(x, y, z)

但是如果这条线

yield tuple([next(it) for it in iters])

取而代之

yield tuple(next(it) for it in iters)

然后一切都停止工作并抛出一个RuntimeError


Tags: infordefargargsitnextyield
1条回答
网友
1楼 · 发布于 2024-05-19 11:03:54

这是Python 3.5中引入的一个特性,而不是一个bug。根据PEP-479,当从生成器内部引发StopIterationRuntimeError会被有意地重新引发,因此现在只有在生成器返回时才可以停止基于生成器的迭代,此时会引发StopIteration异常以停止迭代

否则,在Python 3.5之前,在生成器中任何位置引发的StopIteration异常将停止生成器,而不是传播,因此在以下情况下:

a = list(F(x) for x in xs)
a = [F(x) for x in xs]

如果F(x)在迭代过程中的某个时刻引发StopIteration异常,那么前者将得到截断的结果,这使得调试变得困难,而后者将传播从F(x)引发的异常。该特性的目标是使这两个语句的行为相同,这就是为什么更改会影响生成器而不会影响列表理解

相关问题 更多 >

    热门问题