Добро пожаловать в рекурсию - ее трудно понять, но в ней есть странная элегантность / красота.
Обычно это помогает мне подумать об этом на примере.
Давайтепредположим, этот список: 1, 2, 3
Мы собираемся запустить Max([1,2,3])
- Длина списка равна 3, поэтому мы перейдем к остальной части
- Мы запускаем
Max([2,3])
и сохраняем результат в m
(Рекурсия # 1) - Длина
[2,3]
равна! = 0, мы переходим к остальным - Мы запускаем
Max([3])
и сохраните результат в m
(Рекурсия # 2) - Длина
[3]
равна == 1 - Мы возвращаем индекс 0, который равен
3
(Конециз рекурсии № 2)
- Мы получаем значение
3
для m
- Теперь мы переходим к утверждению
return m if m > list[0] else list[0]
- Резюмируем:
m = 3
и list=[2,3]
m > list[0]
, поэтому мы возвращаем m=3
(Конец рекурсии # 1)
- Время повтора еще раз:
m=3
и list=[1,2,3]
m > list[0]
, поэтому мы возвращаем m=3
Результат Max([1,2,3])
is 3
.
Обратите внимание, что каждый вызов Max
в коде создает "новые" переменные для m
и list
, которые видны только внутриэта функция.Внутренний Max
не знает о m
и list
внешнего Max
и наоборот.
Поток вызовов выглядит следующим образом:
+----------------+
| Max([1,2,3] | +----+
+------^---------+ | Step 1
| |
Step 4 | +--------v------+
+-------+ Max([2,3]) +---+
return 3 +---^-----------+ | Step 2
| |
Step 3 | +---------v-----+
+-----+ Max([3]) |
return 3 +---------------+
К адресу 1):
Когда мы срезаем, используя [n:], это означает:начните с индекса n
и возьмите оставшуюся часть списка.
По адресу 2):
После того, как мы выберемся из рекурсии, см. пример выше.
Дополнительная литература
Изменить в ответ на ваш комментарий
Чтобы помочь вам понять строку return m if m > list[0] else list[0]
Я предлагаю вам попытаться мысленно отслеживать состояние до рекурсивного вызова и после рекурсивного вызова.
Идея этой реализации Max
заключается в следующем: рекурсивно перейти к последнему элементу в списке, затем взять его и проверить его по отношению ко второму-последнему элементу, если последний больше, сохраните это, в противном случае оставьте второй допрошлой.
Если ваш список выглядел следующим образом [1,6,3,5,4,2]
, уровни рекурсии вернули бы это:
Первое число в скобках - m
, а второе - значение list[0]
- 2 (N / A, 2)
- 4 (2, 4)
- 5 (4, 5)
- 5 (5, 3)
- 6 (5, 6)
- 6 (6, 1)
В конечном итоге функция начинается в конце списка, принимает последнийзначение в качестве начального значения и перемещение в начало, при этом всегда сохраняя большее значение, что приводит к возвращению наибольшего значения.
(это трудно описать, надеюсь, вы поймете)