2016-12-08 5 views
0
def test(n): 
    if n == 0: 
     return 
    print("This should print n times") 
    test(n - 1) 

    print("This should not print") 


test(2) 

Выход:Почему я получаю этот вывод с помощью этой рекурсивной функции?

This should print n times 
This should print n times 
This should not print 
This should not print 

Почему This should not print получить распечатан, когда функция вызывает себя (рекурсивно)? Разве это не должно начинаться снова наверху?

+1

первый раз да, но после этого вы возвращаетесь из рекурсивного вызова, и вы достигаете последнего 'print' –

+1

Поскольку рекурсия приостанавливает дальнейшее выполнение до тех пор, пока вызываемая функция не завершится. Сделайте это 'return test (n-1)', если вы не хотите, чтобы «Это не должно печатать». – MSeifert

+0

http://pythontutor.com/ – jonrsharpe

ответ

0

Да, вы частично правы. Когда функция вызывается, она запускается от вершины до конца или ему говорят остановить (например, возврат). После того, как функция была запущена, программа продолжается с линии, на которую она называет функцию. Например.

>>> def myFunc(): 
    print("This function is running") 


>>> def OtherFunc(): 
    myFunc() 
    print("The other function has finished running") 

>>> OtherFunc() 
This function is running 
The other function has finished running 

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

def test(2): 
    if 2 == 0: 
     return 
    print("This should print n times") 
    test(2 - 1) #The program is told to run the function again 

def test(1): 
     if 1 == 0: 
      return 
     print("This should print n times") 
     test(1 - 1) #The program is told to run the function again 

def test(0): 
      if 0 == 0: 
       return #This exits the function, and returns to the function that called it, test(1) 

print("This should not print") #This is the only line left in test(1), so it runs, and the returns to test(2), which called test(1) 

print("This should not print") #This is the only line left in test(2), so it is run. The program ends as there are no more lines of code after when you called test(2) 

Так вызова функции не заканчивается текущий ход функции, которая будет выполняться после того, как функции, которую он называет закончил.

Этот код будет делать то, что вы хотите:

def test(n): 
    if n == 0: 
     return 
    print("This should print n times") 
    test(n - 1) 

    return #This will exit the function 

    print("This should not print") 


test(2) 

Я надеюсь, что это помогло!

0

Нежелательная печать будет выполнена, как только тест (n-1) достигнет своего внутреннего возврата. Возврат завершает только текущий вызов функции, продолжая следующую строку, где он был вызван. Он не очищает весь стек.

0

Welllll в основном. Часть, с которой вы начинаете спотыкаться, - это когда вы говорите «начните сначала». Функция не начинается - звонит сам. Это будет проще увидеть в чистой функции - посмотрите на добавление.

def add(x, y): 
    if y == 0: 
     return x 
    return 1 + add(x, y-1) 

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

>>> add(100, 4) = 1 + add(100, 3) 
    # because we're returning 1 + add(x, y-1) 
... add(100, 3) = 1 + add(100, 2) 
... add(100, 2) = 1 + add(100, 1) 
... add(100, 1) = 1 + add(100, 0) 
... add(100, 0) = 100 # this is called the base case. 

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

>>> add(100, 4) = 1 + (1 + add(100, 2)) # subbing out...add(100, 3) 
       = 1 + (1 + (1 + add(100, 1))) # ... add(100, 2) 
       = 1 + (1 + (1 + (1 + add(100, 0)))) # ... add(100, 1) 
       = 1 + (1 + (1 + (1 + 100))) # ... add(100, 0) 
       = 1 + 1 + 1 + 1 + 100 # because addition is associative 
       = 104 

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

# where a = "This should print n times" 
# and b = "This should not print" 
>>> test(2) = print(a); test(1); print(b) 
... test(1) = print(a); test(0); print(b) 
... test(0) = None # because of the early-exit 

Поп все эти вещи и у вас есть:

>>> test(2) = print(a); (print(a); None; print(b)); print(b) 
#   test(1) ---^ 
#   test(0)---------------^ 

Который имеет 2 print(a) с и 2 print(b) с.

Смежные вопросы