Рекурсии в Python? RuntimeError: максимальная глубина рекурсии превышена при вызове объекта Python [дубликат]

Возможные Дубликаты:
максимальная глубина рекурсии?

у меня есть еще одна проблема с моим кодом. Я пишу свою первую программу в 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

ошибка:

    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

может ли кто-нибудь придумать способ упростить мою функцию?

Я запускаю функцию в то время как цикл:

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)

4 ответов


Python не хватает оптимизаций хвостовой рекурсии, распространенных в функциональных языках, таких как lisp. В Python рекурсия ограничена 999 вызовами (см. sys.getrecursionlimit).

Если глубина 999 больше, чем вы ожидаете, проверьте, отсутствует ли в реализации условие, останавливающее рекурсию, или этот тест может быть неправильным для некоторых случаев.

я осмелюсь сказать, что в Python чистые рекурсивные реализации алгоритмов не являются правильными/безопасными. A реализация fib () ограничена 999 не совсем правильно. Всегда можно преобразовать рекурсивное в итеративное, и это тривиально.

это достигается не часто, потому что во многих рекурсивных алгоритмах глубина имеет тенденцию быть логарифмической. Если это не так с вашим алгоритмом, скорее всего, получите рекурсивные вызовы глубиной более 999, у вас есть два варианта:

1) Вы можете изменить предел рекурсии с помощью sys.setrecursionlimit(n) до максимально допустимого для вашей платформы:

sys.setrecursionlimit(limit):

установите максимальную глубину стека интерпретатора Python для ограничения. Это ограничение предотвращает бесконечную рекурсию от переполнения стека C и сбоя Python.

максимально возможный предел зависит от платформы. Пользователю может потребоваться установить более высокий предел, если у него есть программа, требующая глубокой рекурсии, и платформа, поддерживающая более высокий предел. Это следует делать с осторожностью, потому что слишком высокий предел может привести к крушение.

2) можно преобразовать алгоритм рекурсивного итерационному. Если глубина рекурсии больше, чем разрешено вашей платформой, это единственный способ решить проблему. Если у вас возникли проблемы с этим, задайте новый вопрос, чтобы мы могли помочь.


Я изменил рекурсию на итерацию.

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

работает хорошо :D


ошибка-переполнение стека. Это должно что-то значить на этом сайте, верно? Это происходит потому, что вызов poruszanie приводит к другому вызову poruszanie, увеличивая глубину рекурсии на 1. Второй вызов приводит к другому вызову той же функции. Это происходит снова и снова, каждый раз увеличивая глубину рекурсии.

теперь используемые ресурсы программы ограничены. Каждый вызов функции занимает определенное пространство поверх того, что называется стеком. Если максимальная высота стека достигнута, вы получаете ошибку переполнения стека.


Это ошибки вы получаете, когда функция делает слишком много рекурсивных вызовов для себя. Возможно, это происходит потому, что базовый случай никогда не встречается (и поэтому он застревает в бесконечном цикле) или просто делает большое количество вызовов самому себе. Вы можете заменить рекурсивные вызовы циклами while.