пояснить рекурсивную функцию

def min_list(L):
    if len(L) == 1:
        return L[0]
    return L[0] if L[0] < min_list(L[1:]) else min_list(L[1:])

я понимаю что написано, вернуть первое значение списка, если оно является наименьшим. Если же нет, вернуть весь список со второго элемента –


Ответы (1 шт):

Автор решения: CrazyElf

Под капотом происходит обращение к функции min_list с разными аргументами (какими - вы уже и сами поняли). Вам просто нужно по шагам расписать все эти обращения к функции. Она обращается сама к себе, но всё время меняет аргумент. Нужно просто всё расписать на бумажке и станет понятно.

Посмотрим простейший случай - обращение к функции с L = [1,2,3]:

def min_list([1,2,3]):
    if len([1,2,3]) == 1: # не сработало
        return 1
    return 1 if 1 < min_list([1,2,3][1:]) else min_list([1,2,3][1:])

Этот проход порождает ещё вызовы функции - один с аргументом [2,3] и второй с хм, таким же аргументом (если будет выполнена ветка else). Функция написана не оптимально, не хорошо вызывать два раза с одним аргументом, ну да ладно:

# L = [1,2,3][1:]
def min_list([2,3]):
    if len([2,3]) == 1: # не сработало
        return 2
    return 2 if 2 < min_list([2,3][1:]) else min_list([2,3][1:])

И снова надо вычислить функцию, чтобы отработал if:

# L = [2,3][1:]
def min_list([3]):
    if len([3]) == 1: # сработало!
        return 3
    # дальше код на этом проходе уже не работает, поскольку сработал return

Так, отработал return, возвращаемся на предыдущий шаг, подставив результат работы функции:

#   return 2 if 2 < min_list([2,3][1:]) else min_list([2,3][1:])
    return 2 if 2 < 3 else 3

Отсюда вернётся 2, идём ещё выше по рекурсии:

#    return 1 if 1 < min_list([1,2,3][1:]) else min_list([1,2,3][1:])
     return 1 if 1 < 2 else 2

Возвращается 1. Всё, больше вложенностей не было, это окончательный результат.

→ Ссылка