Вопрос по python, recursion, return – Возврат в рекурсивную функцию

29

Я только начал изучать Python (v3.2.3) и столкнулся со странной проблемойreturn в этой функции:

def test(x):
    if x > 9 :
        test(x - 10)
    else:
        print('real value',x)
        return x

x = int(input())
y = test(x)
print('this should be real value',y)

Когда я запускаю его, я получаю:

45
real value 5
this should be real value None

Но я ожидал:

45
real value 5
this should be real value 5

Я пытался добавитьreturn x внеif и я получил входное значение по умолчанию. Может кто-нибудь, пожалуйста, объясните, какreturn работает?

Это точно так же, как с нерекурсивным вызовом: если вы хотите передать возвращаемое значение из вызванной вами функции, вы должны сделать это самостоятельно, с помощьюreturn ключевое слово. Вызов функции производит ее возвращаемое значение, но вы должны что-то делать с этим возвращаемым значением, независимо от того, является ли вызываемая функция рекурсивной или нет. Karl Knechtel

Ваш Ответ

3   ответа
51

Вы вызываетеtest(45), Это тесты45 > 9, что правда, поэтому он вызываетtest(35) (45 - 10), не возвращая свой результат. То же самое происходит сtest(25) а такжеtest(15)До тех пор, пока, наконец,test(5) вызывается.

Это печатает «реальное значение 5», а затем возвращает 5. Но возвращает результат из функцииalways возвращает его прямому абоненту этой функции. Он не выпрыгивает сразу через несколько вызовов; в конце концов, вызывающая сторона может захотеть что-то сделать с возвращенным результатом, прежде чем вернуть что-тоit's вызывающий абонент. В этом случае толькоtest(5) возвращает что-либо вообще; все остальные зовутtest(x - 10), дождитесь, пока он вернется, проигнорируйте все, что он вернет, а затем (неявно) вернитеNone, С самого внешнего вызоваtest(45) один из этих случаев, что вы получаетеNone.

Вот попытка визуализации того, что происходит:

test(45):
| test(35):
| | test(25):
| | | test(15):
| | | | test(5):
| | | | | print('real value',5)
| | | | | return 5 to test(15)
| | | | return None to test(25)
| | | return None to test(35)
| | return None to test(45)
| return None

Вы не звонилиtest(5) в переводчике,test(5) был вызван изнутри другого вызова функции. Так что возвращение изtest(5) идет кthat function call, Тот факт, что это сама функция, вызывающаяcompletely irrelevant, Вы бы получили точно такие же результаты, если бы ваш код выглядел следующим образом:

def test45(x):
    if x > 9 :
        test35(x - 10)
    else:
        print('real value',x)
        return x

def test35(x):
    if x > 9 :
        test25(x - 10)
    else:
        print('real value',x)
        return x

def test25(x):
    if x > 9 :
        test15(x - 10)
    else:
        print('real value',x)
        return x

def test15(x):
    if x > 9 :
        test5(x - 10)
    else:
        print('real value',x)
        return x

def test5(x):
    if x > 9 :
        print 'No more tests :('
    else:
        print('real value',x)
        return x

Функция test (x), которую вы вызываете с помощью «x = 45»; так же, как звонитьtest45(45), Я надеюсь, вы понимаете, почему очевидно, чтоNone должны быть возвращены при рекурсииisn't участвует. Хорошо, когда рекурсия задействована, ничего не меняется.return оператор не знает и не заботится о том, возвращается ли он из рекурсивно вызванной функции, он ведет себя точно так же в любом случае.

На самом деле рекурсия не является чем-то «особенным». совсем; он ведет себя точно так же, как обычные вызовы функций. Вы получаете информацию от того, что вызвало вас через аргументы, и вы возвращаете информацию тому, что вызвало вас, возвращаясь. Если вы что-то не вернули (возможно, только в одной рукеif), затемNone будет возвращено вашему вызывающему абоненту независимо от того, вызываете ли вы какую-либо другую функцию в этой ветви, независимо от того, что эта функция может вернуть, если вы что-то вызываете, и независимо от того, является ли вызываемая вами функция той же самой функцией, которую вы находитесь внутри ,

4

Вы забыли вернуть значение, когдаx > 9, Без возвращаемого значения функция будет «возвращать»None.

@AlexKey: в приведенном выше коде да, вы вернете значение оценкиtest(x - 10)
Таким образом, в итоге мне нужно поставить возврат на обоих условиях это так? Alex Key
17

Возврат с отступом, поэтому он выполняется только в ветви else. Если берется первая ветвь, функция неявно возвращает None.

Вы должны изменить это на

return test(x-10)
так значит ли это, что мне нужно вернуть даже ложное невыполненное условие if? Alex Key
@AlexKey: Да. посколькуy присваивается значение только из первого вызова функции. Это не то, что является уникальным для Python. Единственная часть, которая уникальна для Python - это то, что функции неявно возвращаютNone когда нет возврата.

Похожие вопросы