2016-03-24 3 views
0

Рассмотрим следующий код:Понимание рекурсивные функции вызовов

def print_mah(n): 
    if n <= 0: 
     return 
    else: 
     print('mah') 
     print_mah(n-1) 

print_mah(3) 

Здесь Python проверяет, если п меньше или равно 0, то он считает, что это Ложные так печатает «ма» и вызывает ту же с n-1 до тех пор, пока n не будет равно 0, поэтому «mah» печатается 3 раза.

Но рассмотрим этот манипулируют код:

def print_mah(n): 
    if n <= 0: 
     return 
    else: 
     print_mah(n-1) 
     print('mah') 

print_mah(3) 

Python проверяет, если п меньше или равно 0, то он считает, что это Ложные так называет ту же функцию снова с п-1, и ' mah 'также печатается 3 раза.

Мой вопрос заключается в том, что почему «ма» не печатается только один раз, другими словами, почему print_mah не вызывается при п = 2, то Python считает, что условие Ложные, так она называет его n = 1 и находит условие: False, поэтому он вызывает его с n == 0 и обнаруживает, что условие равно True, поэтому функция возвращается, и после этого «mah» печатается только один раз ,

+1

Обе версии имеют инструкцию для печати. Один печатает его по пути вниз. Один печатает его по пути вверх. Вы неправильно читаете условие - он проверяет, завершена ли рекурсия. Все остальные случаи включают печать. –

ответ

1

Python считает, что условие ложно, поэтому он называет его с п = 1, и находит условие False, поэтому он вызывает его с n == 0 и находит, что условие равно True, поэтому функция возвращает

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

Поэтому, когда n==1 и рекурсивен с n==0, то он будет возвращен и mah печатается в первый раз, то, что возвращается и mah печатаются при n==2, то, что возвращается и mah печатается третий и последний раз.

+0

Oh! Вы правы, я не знаю, как я это забыл. Большое спасибо! –

1

Чтобы понять разные, возможно, это может помочь.

Алгоритм 1

def print_n(n): 
    if n <= 0: 
     return 
    else: 
     print_n(n-1) 
     print(n) 

Алгоритм 2

def print_n(n): 
    if n <= 0: 
     return 
    else: 
     print(n) 
     print_n(n-1) 

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

Некоторой помощь

При вызове функции (f2) внутри другой функции (f1) текущая функция (f1) будет ждать до тех пор, вызываемой функции (f2) закончен.

Некоторые ключевые слова для исследования

  • вызов функции
  • стек
+0

В первом случае он должен печатать числа от 1 до n в порядке возрастания. Но второй алгоритм должен печатать их в порядке убывания. – Querenker

+0

Вы правы, мне очень жаль! Я допустил ошибку и напечатал печать (3) вместо print_n (3) –

1

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

1

return не вырывается из вашего стека вызовов, только текущий вызов функции. В этом случае:

def print_mah(n): 
    if n <= 0: 
     return 
    else: 
     print_mah(n-1) 
     print('mah') 

print_mah(3) 

print_mah называется три раза, прежде чем вернуться 0. Вы можете думать об этом, как если бы они были только вложенным логика, как это:

def print_mah(n): 
    if n <= 0: 
     return 
    else: 
     print_mah(n-1) # Replace this line with new call 
     print('mah') 

Где мы просто вызываем функцию снова внутри выражения else в комментарии.

def print_mah(n): 
    if n <= 0: 
     #return 
    else: 
     n = n-1 
     if n <= 0: 
      #return 
     else: 
      print_mah(n-1) 
      print('mah') 
     print('mah') 

Вы можете видеть, что печать («Mah») появляется в последовательности в нижней части, которая, как это написано, напечатает последовательно, как функции отступиться из стека вызовов.

1

Вот «след», что делает вторая программа:

print_mah(3) -> 
    print_mah(2) -> 
    print_mah(1) -> 
     print_mah(0) -> 
     # Does nothing, essentially. 
     <- 
     # print_mah(1) continues running. 
     print('mah') # The last thing that print_mah(1) does. 
     <- 
    # print_mah(2) continues running. 
    print('mah') 
    <- 
    # print_mah(3) continues running. 
    print('mah') 
    <- 

То, что мы видим здесь, что print('mah') происходит в три раза (следовательно, «ма» печатается три раза).

1

Вопрос: почему «mah» не печатается один раз, другими словами, почему print_mah не вызывается с n = 2, тогда Python обнаруживает, что это условие False, поэтому он вызывает его с помощью n = 1 и находит условие False, поэтому он вызывает его с n == 0 и обнаруживает, что условие имеет значение True, поэтому функция возвращает, а после этого «mah» печатается только один раз.

Функция возвращается только из самой внутренней функции. Два уровня функций, в которых используется условие else, будут продолжать выполнение после вызова print_mah и фактически распечатать. Ниже приведена схема проезда для print_mah(2) для краткости.

print_mah(2) 
# Enter print_mah - Level 1 

    if n <= 0: # n = 2 
     # ... 
    # False, continue to else 

    else: 
     print_mah(n-1) # n = 2 
    # Enter print_mah - Level 2 

     if n <= 0: # n = 1 
     # ... 
     # False, continue to else 

     else: 
      print_mah(n-1) # n = 1 
     # Enter print_mah - Level 3 

      if n <= 0: # n = 0 
       return 
      # Return None to print_mah - Level 2 

     print('mah') 
     # Function is complete, return None to print_mah - Level 1 

    print('mah') 
    # Function is complete, return None to the execution scope 
Смежные вопросы