Python索引时的递归限制

Python索引时的递归限制,python,python-3.x,recursion,stack-overflow,Python,Python 3.x,Recursion,Stack Overflow,我在Python中胡闹,可以使用sys.setrecursionlimit(limit)动态更改。下面的代码演示了整数限制与递归函数调用允许的最大深度完全对应 对于使用[]的递归索引,相同的递归限制似乎适用,但显然是因子3,这意味着我可以索引比调用深度深三倍: 上面的图是由下面的代码生成的 import itertools, sys import numpy as np import matplotlib.pyplot as plt limits = np.arange(10, 500, 1

我在Python中胡闹,可以使用
sys.setrecursionlimit(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]…
,然后对其进行动态计算


问题:解释这个3的因子。

l[-1][-1]中没有递归。
-它编译为“push
l
;用最后一个元素替换堆栈顶部;替换…”。您的
RecursionError
来自编译长字符串


从字面上看,有一种方法可以用来近似地表示字节编译器与解释器本身的堆栈使用情况。(Python2没有这样的限制,只是在这样的表达式上崩溃了。)

在我的例子中,call的系数约为0.58,getitem的系数约为1.75,这就更不合理了。。。1.75/0.58仍然是3左右,这是因为深度很小。当我增加限制时,实际上接近1和3。我仍然停留在1以下的通话,虽然直觉上它应该是完全1的所有情况。有兴趣知道什么隐藏的机制在这里工作…奇怪。我在Python3.7和3.5上都找到了1.00和3.00,64位LinuxMint。我猜这可能与平台有关?@Julien:一些限制被扩展到测试代码上,并提供了一个恒定的偏移量。