Python中的递归?运行时错误:调用 Python 对象时超出了最大递归深度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14222416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:47:50  来源:igfitidea点击:

Recursion in Python? RuntimeError: maximum recursion depth exceeded while calling a Python object

pythonrecursionruntime-errorsimulationvpython

提问by Emil Sm?t

Possible Duplicate:
Maximum recursion depth?

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

I have another problem with my code. I'm wrtiting my first program in Vpython and I have to make a simulation of mixing two gases. First i had a problem with borders, but now when the balls(that represents the gas particles) stay within the borders there is sth different wrong. After a few seconds i get an error, which is shown below the source code of my function. Code:

我的代码还有另一个问题。我正在用 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

the error is:

错误是:

    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

Can anybody think of a way to simplify my function?

有人能想出一种方法来简化我的功能吗?

I run the function it while loop:

我在循环中运行它的函数:

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)

采纳答案by Paulo Scardine

Python lacks the tail recursion optimizations common in functional languages like lisp. In Python, recursion is limited to 999 calls (see sys.getrecursionlimit).

Python 缺少函数式语言(如 lisp)中常见的尾递归优化。在 Python 中,递归限制为 999 次调用(请参阅sys.getrecursionlimit)。

If 999 depth is more than you are expecting, check if the implementation lacks a condition that stops recursion, or if this test may be wrong for some cases.

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

I dare to say that in Python, pure recursive algorithm implementations are not correct/safe. A fib() implementation limited to 999 is not really correct. It is always possible to convert recursive into iterative, and doing so is trivial.

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

It is not reached often because in many recursive algorithms the depth tend to be logarithmic. If it is not the case with your algorithm and you expect recursion deeper than 999 calls you have two options:

它并不经常达到,因为在许多递归算法中,深度往往是对数的。如果您的算法不是这种情况,并且您希望递归比 999 次调用更深,那么您有两种选择:

1) You can change the recursion limit with sys.setrecursionlimit(n)until the maximum allowed for your platform:

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

sys.setrecursionlimit(limit):

Set the maximum depth of the Python interpreter stack to limit. This limit prevents infinite recursion from causing an overflow of the C stack and crashing Python.

The highest possible limit is platform-dependent. A user may need to set the limit higher when she has a program that requires deep recursion and a platform that supports a higher limit. This should be done with care, because a too-high limit can lead to a crash.

sys.setrecursionlimit(limit)

将 Python 解释器堆栈的最大深度设置为 limit。此限制可防止无限递归导致 C 堆栈溢出和 Python 崩溃。

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

2) You can try to convert the algorithm from recursive to iterative. If recursion depth is bigger than allowed by your platform, it is the only way to fix the problem. There are step by step instructions on the Internetand it should be a straightforward operation for someone with some CS education. If you are having trouble with that, post a new question so we can help.

2)您可以尝试将算法从递归转换为迭代。如果递归深度大于平台允许的范围,这是解决问题的唯一方法。有一步一步的指示在互联网上,它应该是有人用一些CS教育简单的操作。如果您对此有疑问,请发布一个新问题,以便我们提供帮助。

回答by pvoosten

The error is a stack overflow. That should ring a bell on this site, right? It occurs because a call to poruszanieresults in another call to poruszanie, incrementing the recursion depth by 1. The second call results in another call to the same function. That happens over and over again, each time incrementing the recursion depth.

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

Now, the usable resources of a program are limited. Each function call takes a certain amount of space on top of what is called the stack. If the maximum stack height is reached, you get a stack overflow error.

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

回答by mojzu

That's the error you get when a function makes too many recursive calls to itself. It might be doing this because the base case is never met (and therefore it gets stuck in an infinite loop) or just by making an large number of calls to itself. You could replace the recursive calls with while loops.

这就是函数对自身进行过多递归调用时得到的错误。这样做可能是因为从未满足基本情况(因此它陷入无限循环)或只是通过对其自身进行大量调用。您可以用 while 循环替换递归调用。

回答by Emil Sm?t

I've changed the recursion to iteration.

我已将递归更改为迭代。

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

Works good :D

效果很好:D