【发布时间】:2019-06-22 00:52:00
【问题描述】:
我在 Python 中玩弄 recursion limit,它可以使用 sys.setrecursionlimit(limit) 动态更改。下面的代码演示了整数 limit 完全对应于递归函数调用允许的最大深度。
对于使用[] 的递归索引,似乎适用相同的递归限制,但显然系数为 3,这意味着我可以索引的深度是我调用的三倍:
上面的图是由下面的代码生成的。
import itertools, sys
import numpy as np
import matplotlib.pyplot as plt
limits = np.arange(10, 500, 100)
# Find max depth of recursive calls
maxdepth = []
for limit in limits:
sys.setrecursionlimit(limit)
try:
n = [0]
def fun(n=n):
n[0] += 1
fun()
fun()
except RecursionError:
maxdepth.append(n[0])
a, b = np.polyfit(limits, maxdepth, 1)
plt.plot(limits, maxdepth, '*')
plt.plot(limits, a*limits + b, '-', label='call')
plt.text(np.mean(limits), a*np.mean(limits) + b, f'slope = {a:.2f}')
# Find max depth of getitem
maxdepth = []
n = 0
l = []; l.append(l)
for limit in limits:
sys.setrecursionlimit(limit)
for n in itertools.count(n):
try:
eval('l' + '[-1]'*n)
except RecursionError:
break
maxdepth.append(n)
a, b = np.polyfit(limits, maxdepth, 1)
plt.plot(limits, maxdepth, '*')
plt.plot(limits, a*limits + b, '-', label='getitem')
plt.text(np.mean(limits), a*np.mean(limits) + b, f'slope = {a:.2f}')
plt.xlabel('Recursion limit')
plt.ylabel('Max depth')
plt.legend()
plt.savefig('test.png')
为了测试递归索引,我将一个列表 l 附加到自身并构造一个长文本 [-1][-1][-1]...,然后我动态评估 l。
问题:解释这个因数 3。
【问题讨论】:
-
在我的情况下,我得到一个大约 0.58 的 call 和 1.75 的 getitem 因子,这更没有意义......虽然 1.75/0.58 仍然是 3 左右。
-
那是为了小深度。随着我增加限制,实际上更接近 1 和 3。我仍然保持在 1 以下,但对于所有情况,直觉上它应该正好是 1。有兴趣知道这里的隐藏机制是什么......
-
奇怪。我在 Python 3.7 和 3.5、64 位 Linux Mint 上都找到了 1.00 和 3.00。我猜这可能取决于平台?
-
@Julien:一些限制用于测试代码并提供恒定的偏移量。
标签: python python-3.x recursion stack-overflow