Не понимаю вывод рекурсивной функции - PullRequest
0 голосов
/ 27 февраля 2020
def some_func(count):
    if count > 0:
        some_func(count-1)
        print(count)

print(some_func(5))

Вывод

1
2
3
4
5

В моем понимании, функция будет уменьшена до some_fun c (0) и выведет 0 в качестве окончательного вывода. Но фактический выход составляет от 1 до 5? Что происходит с каждой итерацией?

Заранее спасибо!

Ответы [ 2 ]

4 голосов
/ 27 февраля 2020

Обратите внимание на порядок выполнения оператора!

some_func(5)
-- some_func(4)
---- some_func(3)
------ some_func(2)
-------- some_func(1)
---------- some_func(0)
---------- print(1)
-------- print(2)
------ print(3)
---- print(4)
-- print(5)

В some_func(0) условие 0>0 не выполняется, поэтому вызов функций some_func и print(0) пропускается.

2 голосов
/ 27 февраля 2020

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

def some_func(count):
    if count > 0:
        some_func(count-1)
        print(count)

print(some_func(5))

Причина в том, что в рекурсии код рядом с рекурсивным Вызов помещается в стековую память, которая является структурой Last in First Out, вы можете найти больше информации об этом здесь stack и до тех пор, пока не наступит условие завершения для кода, толчки последующих операторов продолжают происходить в вершина стека. Пример визуализации того, что происходит после вызова print(some_func(5))

  1. print(some_func(5)): 5> 0 => True, поэтому следующий cmd some_fun c (5-1) вызывается в этом В момент, когда происходит что-то интересное, в пространстве стека помещаются все последующие операторы some_func(count-1), а затем начинается фактический вызов метода, поэтому в этот момент стек будет выглядеть следующим образом:
| TOP_OF_STACK |
|--------------|
| print(5)     |
Следующая строка для вызова: some_fun c (4): затем снова 4> 0 => True, поэтому вызывается some_fun c (4-1) и последующий вывод print (4) помещается в стек как показано ниже:
| TOP_OF_STACK |
|--------------|
| print(4)     |
|--------------|
| print(5)     |
some_fun c (3): 3> ​​0 => True, вызовите some_fun c (3-1) и pu sh print (3) на вершине стека.
| TOP_OF_STACK |
|--------------|
| print(3)     |
|--------------|
| print(4)     |
|--------------|
| print(5)     |

То же самое происходит для some_fun c (2) и some_fun c (1), конец которого выглядит следующим образом:

| TOP_OF_STACK |
|--------------|
| print(1)     |
|--------------|
| print(2)     |
|--------------|
| print(3)     |
|--------------|
| print(4)     |
|--------------|
| print(5)     |

Когда some_fun c (0) вызывается следующее thign происходит: 0> 0 => false, поэтому никакие дальнейшие операторы, следующие после if, не будут вызваны, и все операторы, которые были помещены в стек до сих пор, будут выталкиваться последовательно сверху, что приводит к выполнению операторов print, что приводит к выводу:

1
2
3
4
5

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

Надеюсь, это поможет вам лучше понять рекурсивный поток.

...