python递归函数错误RuntimeError:超过最大递归深度

python递归函数错误RuntimeError:超过最大递归深度,python,recursion,python-2.7,Python,Recursion,Python 2.7,我有这个剧本: def number_of_occurences(c, message): position = message.find(c) if position == -1: return 0 else: if len(message[position:]) == 0: return position else: return position + number_of_occurences(c, message[position

我有这个剧本:

def number_of_occurences(c, message):
  position = message.find(c)
  if position == -1:
    return 0
  else:
    if len(message[position:]) == 0:
      return position
    else:
      return position + number_of_occurences(c, message[position:])

number_of_occurences('a', 'azertya')
但当我运行它时,我得到了以下错误:

Traceback (most recent call last):
  File "frequency_analysis.py", line 31, in <module>
    number_of_occurences('a', 'azertya')
  File "file_name.py", line 29, in number_of_occurences
    return position + number_of_occurences(c, message[position:])
...
...
...
  File "file_name.py", line 29, in number_of_occurences
    return position + number_of_occurences(c, message[position:])
RuntimeError: maximum recursion depth exceeded
这是:

sys.setrecursionlimit(30000)
但对于这一点:

sys.setrecursionlimit(10000)
sys.setrecursionlimit(50000)
它给出了以下错误:

Traceback (most recent call last):
  File "frequency_analysis.py", line 31, in <module>
    number_of_occurences('a', 'azertya')
  File "file_name.py", line 29, in number_of_occurences
    return position + number_of_occurences(c, message[position:])
...
...
...
  File "file_name.py", line 29, in number_of_occurences
    return position + number_of_occurences(c, message[position:])
RuntimeError: maximum recursion depth exceeded
分段故障(堆芯转储)

我做错了什么?提前谢谢

更新: 感谢您,以下是正确的代码:

def number_of_occurences(c, message):
  position = message.find(c)
  nbr = 0.0
  if position == -1:
    return 0
  else:
    nbr += 1
    if len(message[position:]) == 0:
      return nbr
    else:
      return nbr + number_of_occurences(c, message[position + 1:])

问题是,您使用相同的参数递归地调用自己,这保证了无限递归。不管你设置的递归限制有多高;你不能设定它超过无穷大*


使用您的参数手动跟踪它

position = message.find(c) # = 'azertya'.find('a') = 0
if position == -1: # Nope
else:
    if len(message[position:]) == 0: # len('azertya'[0:]) == len('azertya') == 7 != 0
    else:
        return position + number_of_occurences(c, message[position:])
            # 0 + number_of_occurences('a', 'azertya'[0:])
            # == 0 + number_of_occurences('a', 'azertya')
            # which is exactly what we were called with
即使不以第一个字符开头,如果以字符串中的任何字符开头,最终也会遇到同样的问题。再次尝试使用
'r'
而不是
'a'
进行跟踪

运行一个交互式可视化工具比手动跟踪要简单得多(而且更漂亮,更难出错)

或者,尝试每次打印
ing
c
message
position
,应该可以清楚地看到发生了什么

解决方法非常简单:

return position + number_of_occurences(c, message[position+1:])


*即使可以,只要堆栈与堆发生冲突,就会出现segfault,至少对于CPython是这样。这就是为什么你只有5万美元。但即使使用不同的实现,如Stackless或PyPy,一旦没有空间容纳更多堆栈帧,也会出现内存错误。但是,如果你有无限的寻址位和无限的虚拟页表空间,因此这不是问题,并且愿意永远等待……它仍然不起作用,但至少不会失败。

它在什么方面没有帮助?它花费了更长的时间,但给出了相同的错误。问题是(a)递归限制太低,因为你需要, 20000? (b) 您认为代码中的递归深度远远低于任何合理的限制(比如低于10)?(c) 你知道你得到的递归要么是无限的,要么是太深的,你想知道为什么你的代码会这样做?如果位置等于零,那么你将继续进行递归调用。尽管有一些函数式原语,Python缺乏纯函数式语言中常见的尾部调用优化。大多数情况下,以迭代的方式重写任何递归算法都很简单,这是Python中惯用的形式。