Python中的递归?RuntimeError:调用Python对象时超出了最大递归深度

Emi*_*męt 10 python simulation recursion runtime-error vpython

可能重复:
最大递归深度?

我的代码有另一个问题.我正在研究我在Vpython中的第一个程序,我必须模拟混合两种气体.首先我遇到了边界问题,但现在当球(代表气体粒子)留在边界内时,存在不同的错误.几秒钟后,我收到一个错误,该错误显示在我的函数的源代码下面.码:

def MovingTheBall(listOfBalls,position,numCell,flagOfExecution):
    flag = 0
    if flagOfExecution==0:
        positionTmp = position
    else:
        positionTmp = (position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0)
    for i in range( 0, len(listOfBalls) ):
        if positionTmp==listOfBalls[i].pos:
            flag=1


    if flag==1:
        return MovingTheBall(lista,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
    else:
        if positionTmp[0]==0 or positionTmp[0]>=numCell or positionTmp[0]<=-numCell or positionTmp[1]>=numCell or positionTmp[1]<=-numCell:
            return MovingTheBall(lista,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)

        return positionTmp
Run Code Online (Sandbox Code Playgroud)

错误是:

    return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
  File "gaz.txt", line 138, in MovingTheBall
    return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
  File "gaz.txt", line 138, in MovingTheBall
    return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
  File "gaz.txt", line 138, in MovingTheBall
    return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
  File "gaz.txt", line 138, in MovingTheBall
    return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
  File "gaz.txt", line 138, in MovingTheBall
    return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
  File "gaz.txt", line 130, in MovingTheBall
    if positionTmp==listOfBalls[i].pos:
RuntimeError: maximum recursion depth exceeded while calling a Python object
Run Code Online (Sandbox Code Playgroud)

任何人都可以想出一种简化我的功能的方法吗?

我在循环时运行它的功能:

while 1:
        rate(20)
        for i in range(0,len(self.listOfBalls)):
            self.listOfBalls[i].pos=poruszanie(self.listOfBalls,self.listOfBalls[i].pos,self.numCell,0)
Run Code Online (Sandbox Code Playgroud)

Pau*_*ine 27

Python缺乏像lisp这样的函数式语言中常见的尾递归优化.在Python中,递归仅限于999次调用(请参阅sys.getrecursionlimit).

如果999深度超出了您的预期,请检查实现是否缺少阻止递归的条件,或者在某些情况下此测试可能是错误的.

我敢说,在Python中,纯递归算法实现不正确/安全.限制为999的fib()实现并不正确.总是可以将递归转换为迭代,这样做是微不足道的.

它并不常见,因为在许多递归算法中,深度往往是对数的.如果不是你的算法的情况可能会得到超过999深度的递归调用,你有两个选择:

1)您可以更改递归限制,sys.setrecursionlimit(n)直到您的平台允许的最大值:

sys.setrecursionlimit(limit):

设置Python解释器堆栈的最大深度以限制.此限制可防止无限递归导致C堆栈溢出并导致Python崩溃.

最高可能的限制取决于平台.当用户具有需要深度递归的程序和支持更高限制的平台时,用户可能需要将限制设置得更高.这应该小心,因为过高的限制可能导致崩溃.

2)您可以转换为将算法从递归转换为迭代.如果递归深度大于平台允许的深度,则是解决问题的唯一方法.如果您遇到问题,请发布一个新问题,以便我们提供帮助.

  • 我不同意将递归算法改为迭代算法是微不足道的. (3认同)
  • 抱歉,我发现您的代码很难理解,并且无法指出错误所在。更新了答案,并提供了有关如何解决问题的建议,要么检查为什么不停止递归,要么更改为非递归方法(有一些通用技术可以将递归实现转换为非递归实现)。 (2认同)

pvo*_*ten 6

错误是堆栈溢出。这应该在这个网站上敲响警钟,对吧?发生这种情况是因为对 的调用poruszanie导致对 的另一次调用poruszanie,将递归深度增加 1。第二次调用导致对同一函数的另一次调用。这种情况一遍又一遍地发生,每次都增加递归深度。

现在,程序的可用资源是有限的。每个函数调用都在称为堆栈的顶部占用一定量的空间。如果达到最大堆栈高度,则会出现堆栈溢出错误。


Emi*_*męt 6

我已经将递归更改为迭代.

def MovingTheBall(listOfBalls,position,numCell):
while 1:
    stop=1
    positionTmp = (position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0)
    for i in range(0,len(listOfBalls)):
        if positionTmp==listOfBalls[i].pos:
            stop=0
    if stop==1:
        if (positionTmp[0]==0 or positionTmp[0]>=numCell or positionTmp[0]<=-numCell or positionTmp[1]>=numCell or positionTmp[1]<=-numCell):
            stop=0
        else:
            return positionTmp
Run Code Online (Sandbox Code Playgroud)

效果很好:D