索引时 Python 中的递归限制
Recursion limit in Python when indexing
我在 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 的因数。
在l[-1][-1]…
中没有递归——它编译为“push l
;用最后一个元素替换栈顶;代替…”。您的 RecursionError
来自 编译 长字符串。
字面上有一个 factor of 3 用于近似字节编译器 与 解释器的堆栈使用情况。 (Python 2 没有这样的限制,只会在这样的表达式上崩溃。)
我在 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 的因数。
在l[-1][-1]…
中没有递归——它编译为“push l
;用最后一个元素替换栈顶;代替…”。您的 RecursionError
来自 编译 长字符串。
字面上有一个 factor of 3 用于近似字节编译器 与 解释器的堆栈使用情况。 (Python 2 没有这样的限制,只会在这样的表达式上崩溃。)