Поведение возврата в рекурсивной функции

#python #python-3.x #recursion #return

Вопрос:

Я не могу полностью сосредоточиться на поведении return операторов в приведенной ниже рекурсивной функции. Имея возвращаемые значения в обоих операторах if and else , я получаю int значение, возвращаемое по желанию, однако либо с удаленным возвращением функций None .

Я ожидал, что внутри потребуется только оператор return else , так как любая итерация, выполняемая с помощью if оператора, будет рекурсивно инициировать функцию calculate до тех пор, пока она не пройдет if

 def solution(n, b):
    results = {}
    j = 0
    k = len(str(n))
    return calculate(n, b, j, k, results)


def calculate(n, b, j, k, results):
    i = ''
    x = ''.join(sorted([i for i in str(n)])[::-1])
    y = x[::-1]
    z = int(x, b) - int(y, b)
    while z:
        i = int(str(z % b)   str(i))
        z = z // b
    i = '0'*(k-len(str(i)))   str(i)
    if i not in results.values():
        results[j] = i
        j  = 1
        s = calculate(i, b, j, k, results)
        return s #commenting this line causes code to return None
    else: #commenting else statement causes code to return None
        return len(results.keys()) - list(results.keys())[list(results.values()).index(i)]


print(solution('210022', 3))
 

Комментарии:

1. помимо закомментированного else заявления, вам необходимо уменьшить отступ его возврата

Ответ №1:

все функции, рекурсивные или иные, которые завершают свое выполнение, возвращают значение, если в операторе не указано явное значение return , то None по умолчанию a доставляется вызывающему.

Возьмем, к примеру, этот пример функции:

 >>> def test(x):
        if x:
            s="if case"
        else:
            return "else case"

    
>>> print(test(True))
None
>>> print(test(False))
else case
>>> 
 

Здесь в первом случае вы вводите «если случай», выполняете весь блок кода там, потому что оператор return отсутствует, вы оставляете блок кода if-else и переходите к следующему, но в этом случае больше нет фрагмента кода для запуска, поэтому функция завершает выполнение, не возвращая по умолчанию ни одного.

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

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

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

Вот второй пример с факториальной функцией

 >>> def fact_bad(n,r=1):
        if n<=1:
            return r
        else:
            ans=fact_bad(n-1,n*r)

        
>>> def fact_good(n,r=1):
        if n<=1:
            return r
        else:
            ans=fact_good(n-1,n*r)
            return ans

    
>>> fact_bad(5) #you get nothing here because you do nothing with your recursive call inside
>>> fact_good(5) #you get your result as desire because because you do something with your recursive call inside, in this case that is just returning it
120
>>> 
 

Комментарии:

1. Спасибо за эту запись. Ваши упрощенные примеры помогли мне понять, что каждый вызов рекурсивной функции должен «возвращать» и завершать оператор «если», из которого он был вызван, и каждый «возврат» приводит к окончательному оператору else «возврат» из самого глубокого вызова функции.