gpt4 book ai didi

python - 当递归非常深入时,理解中的递归调用有什么特别之处?

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

我注意到当我在列表理解中使用递归时会发生一些奇怪的事情。如果递归太深,解释器似乎会空闲(我等了 5 分钟,但什么也没发生)。

为了这个问题,假设我想展平嵌套列表(我不想 - 但这是一个说明我遇到的问题的简短代码示例):

def flatten(x):
if isinstance(x, list):
return [a for i in x for a in flatten(i)]
else:
return [x]

使用辅助函数创建嵌套列表:

def wrap_in_lists(value, depth):
a = value
for _ in range(depth):
a = [a]
return a

它在使用时效果很好:

>>> flatten(wrap_in_lists(1, 2**10))
[1]

但是当我使用时它完全停止了:

>>> flatten(wrap_in_lists(1, 2**11))
# Nothing happens, no exception, no result, no segfault, ...

我的问题是:这里发生了什么?为什么一点 react 都没有?


奇怪的是,使用生成器的类似方法并没有表现出这种行为:

def flatten(l):
def inner(x):
for item in x:
if isinstance(item, list):
yield from inner(item)
else:
yield item
return list(inner(l))

>>> flatten(wrap_in_lists(1, 2**11))
[1]

>>> # although increasing the depth leads to an recursion error
>>> flatten(wrap_in_lists(1, 2**12))
RecursionError: maximum recursion depth exceeded

如果这很重要,我会在 jupyter 实验室的 Windows 上使用 Python 64 位 3.6.6。

最佳答案

这是一个简单的 StackOverflow,发生在 达到递归限制之前。

在第二种(生成器)方法中,它达到了深度为 2**12 的递归限制.这意味着 2**11应该在第一种方法中达到递归限制。那是因为列表推导式创建了一个额外的堆栈框架,因此它的堆栈框架是生成器解决方案的两倍。它没有抛出 RecursionError 的事实意味着解释器发生了“致命”的事情(或者某处存在无限循环)。

但这不是无限循环,因为如果您检查 jupyter 实验室响应(例如,如果您从命令行使用 jupyter lab 启动它),您会注意到在运行 flatten(wrap_in_lists(1, 2**11)) 后不久行它会打印一个 kernel <xyz> restarted .所以没有响应是不正确的,内核刚刚崩溃并且 [*]在这种情况下显示在 jupyter lab 单元格中仅表示计算未完成(因为崩溃)。

如果您更改 Python 的递归限制或使用为您更改它的解释器,这就是为什么您要非常小心的原因之一。

关于python - 当递归非常深入时,理解中的递归调用有什么特别之处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51337082/

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