这个算法中的Python尾部递归优化?

这个算法中的Python尾部递归优化?,python,recursion,Python,Recursion,我遇到了以下问题: 让我们考虑下面的编码表: 0 -> A 1 -> B 2 -> C ... 输入:包含整数列表的字符串 输出:int表示可以从输入编码的字数 示例: 我写了这个算法 导入字符串 sys.setrecursionlimit(100)#将递归次数限制为100 #{0:a',1:b',等} dict_values=dict(zip(范围(26),string.ascii_小写)) def计数分割(列表编号:列表)->int: 如果len(列表编号)=0: 返

我遇到了以下问题: 让我们考虑下面的编码表:

0 -> A
1 -> B
2 -> C
...
  • 输入:包含整数列表的字符串
  • 输出:int表示可以从输入编码的字数
  • 示例:
我写了这个算法

导入字符串
sys.setrecursionlimit(100)#将递归次数限制为100
#{0:a',1:b',等}
dict_values=dict(zip(范围(26),string.ascii_小写))
def计数分割(列表编号:列表)->int:
如果len(列表编号)=0:
返回0
elif len(列表编号)=1:
返回1
elif len(列表编号)=2:
如果int(列表编号[0])==0:
返回1
elif 10 3
#打印(获取单词(“124”)->3
#打印(获取单词(“368”)->1
#打印(获取单词(“322”)->2
#打印(获取单词(“12121212”)->10946
令人惊讶的是,这个算法适用于最后一个示例
“12121212”
。我希望递归的次数会超过,因为在每个步骤中,函数
count\u split
在列表中被调用两次。因此,通话次数远远超过100次(甚至超过1000次)

与此同时,我发现说尾部递归在Python中没有优化,所以我有点惊讶


有人能给我解释一下为什么这个算法没有超过递归限制吗?

你关心递归深度,即调用堆栈的最大深度(高度?)

这里有一个实证方法:(测量深度的代码)

导入字符串,sys sys.setrecursionlimit(100)#将递归次数限制为100 dict_values=dict(zip(范围(26),string.ascii_小写)) 堆栈=[] 最大深度=0 def计数分割(列表编号:列表)->int: 全局最大深度 stack.append(无) 最大深度=最大(最大深度,透镜(堆栈)) 如果len(列表编号)=0: 返回0 elif len(列表编号)=1: 返回1 elif len(列表编号)=2: 如果int(列表编号[0])==0: 返回1
elif 10对我来说有点晚了,但我认为最大递归深度(这才是最重要的)只与输入字符串的长度有关,不是吗?注意,
recursionlimit
有点误导,它实际上是调用堆栈的最大深度。是的,所以我猜递归深度(默认设置为1000)不是调用函数的次数,而是调用函数的输入数。我说得对吗?不,不是调用函数的输入数。这是调用堆栈的最大深度,还是你的意思?再一次,对不起,对我来说太晚了好吧,代表连续调用的树的深度,对吗?它不是树,而是堆栈。
"0" -> 1 (word is A)
"10" -> 2 (words are BA and K)
"121" -> 3 (words are BCB, MB and BV) 
import string, sys
sys.setrecursionlimit(100)  # limit the number of recursions to 100

dict_values = dict(zip(range(26), string.ascii_lowercase))
stack = []
max_depth = 0
def count_split(list_numbers: list) -> int:
    global max_depth
    stack.append(None)
    max_depth = max(max_depth, len(stack))
    if len(list_numbers) == 0:
        return 0

    elif len(list_numbers) == 1:
        return 1

    elif len(list_numbers) == 2:
        if int(list_numbers[0]) == 0:
            return 1

        elif 10 <= int("".join(list_numbers)) <= 25:
            return 2

        else:
            return 1

    else:  # list_numbers contains at least three elements
        if count_split(list_numbers[:2]) == 2:
            stack.pop()
            result = count_split(list_numbers[1:]) + count_split(list_numbers[2:])
            stack.pop(); stack.pop()
            return result

        else:
            result = count_split(list_numbers[1:])
            stack.pop()
            return result

def get_nb_words(code: str) -> int:
    return count_split(list(code))

print(get_nb_words("12121212121212121212"))
print(max_depth) # 20