От новичка до гуру: Курсы программирования на CyberDuff

Почему этот оператор возврата выдает ошибку в этой рекурсивной функции Python?

Я практикую использование рекурсивных функций, суммируя все элементы в списке.

Функция, которую я сделал, была:

def list_sum_recursive(input_list):

    #base case, list is empty
    if input_list == []:
        print("empty")
        return

    #recursive case
    else:
        #grab the first element
        head = input_list[0]
        del input_list[0]
        #return the sum of the head plus the sum of the rest of the list
        return head + list_sum_recursive(input_list)

Однако эта функция выдает эту ошибку:

TypeError: неподдерживаемые типы операндов для +: 'int' и 'NoneType

Я нашел решение, сделав базовый вариант return 0 вместо return.

Но теперь мне любопытно, что делала или не делала простая return, чтобы выдать ошибку? И почему в Python, довольно гибком и щадящем языке, возникает такая проблема?

15.06.2019

  • Быть гибким и снисходительным не означает, что язык должен догадываться о том, что вы хотите. return сам по себе неявно возвращает None. Это правило языка 15.06.2019
  • Простое возвращение возвращает None, поэтому, когда вы делаете это return head + list_sum_recursive(input_list), вы добавляете head к None, когда достигается базовый случай. Это неумолимо, потому что Python является строго типизированным языком, что помогает избежать некоторых ошибок, которые могут возникнуть, если вы предполагаете, что None должно автоматически преобразовываться в ноль. 15.06.2019
  • Все вызовы функций в Python возвращают значение. Если выполняется голый return или если выполнение падает с конца функции без выполнения return, то они неявно возвращают None. Не существует концепции типа void, который выдает ошибку при попытке его использования. 15.06.2019
  • Благодарю за разъяснение. Я не знал, что голый оператор возврата имеет возвращаемый тип None. 15.06.2019

Ответы:


1

Просто хочу дать вам более питоническую версию, надеюсь, вы не возражаете.

def list_sum_recursive(input_list):

    #base case, list is empty
    if not input_list:
        return 0
    #return the sum of the head plus the sum of the rest of the list
    return input_list.pop(0) + list_sum_recursive(input_list)

print(list_sum_recursive([1,2,3]))
15.06.2019
  • Да, я бы использовал input_list[0] + list_sum_recursive([input_list[1:]). Я немного беспокоюсь, изменяя список и используя его в одном заявлении. 15.06.2019
  • @Deepstop Да, ломтик выглядит безопаснее и, возможно, удобнее для большего количества людей. 15.06.2019
  • Мне нравится как метод выдавливания, так и метод нарезки. Это те вещи, которые мне нужно начать искать в моем коде. очень чисто 16.06.2019

  • 2

    Как указано в комментариях, не возвращайте None в первом разделе. Вместо этого верните 0.

    def list_sum_recursive(input_list):
    
        #base case, list is empty
        if input_list == []:
        #    print("empty")
            return 0
    
        #recursive case
        else:
            #grab the first element
            head = input_list[0]
            del input_list[0]
            #return the sum of the head plus the sum of the rest of the list
            return head + list_sum_recursive(input_list)
    
    print(list_sum_recursive([1,2,3]))
    

    Запуск программы дает нам

    $ python test.py
    6
    
    15.06.2019

    3
    def list_sum_recursive(input_list):
    
        #base case, list is empty
        if input_list == []:
            print("empty")
            return
    
        #recursive case
        else:
            #grab the first element
            head = input_list[0]
            del input_list[0]
            #return the sum of the head plus the sum of the rest of the list
            x=list_sum_recursive(input_list)
            if(x==None):
                return head + 0
            else:
                return head+x
    

    вернуть 0 вместо нуля. или вы можете сделать этот трюк.

    15.06.2019
    Новые материалы

    5 простых концепций Python, ставших сложными
    #заранее извините 1) Переменные x = 4 y = 5 Переменная в Python — это символическое представление объекта. После присвоения некоторого объекта переменной Python мы приобретаем..

    «Освоение вероятности: изучение совместной, предельной, условной вероятности и теоремы Байеса —…
    Виды вероятности: Совместная вероятность Предельная вероятность Условная вероятность Диаграмма Венна в вероятностях: В “Set Theory” мы создаем диаграмму Венна...

    Основы Spring: Bean-компоненты, контейнер и внедрение зависимостей
    Как лего может помочь нашему пониманию Когда мы начинаем использовать Spring, нам бросают много терминов, и может быть трудно понять, что они все означают. Итак, мы разберем основы и будем..

    Отслеживание состояния с течением времени с дифференцированием снимков
    Время от времени что-то происходит и революционизирует часть моего рабочего процесса разработки. Что-то более забавное вместо типичного утомительного и утомительного процесса разработки. В..

    Я предполагаю, что вы имеете в виду методы обработки категориальных данных.
    Я предполагаю, что вы имеете в виду методы обработки категориальных данных. Пожалуйста, проверьте мой пост Инструментарий специалиста по данным для кодирования категориальных переменных в..

    Игра в прятки с данными
    Игра в прятки с данными Я хотел бы, чтобы вы сделали мне одолжение и ответили на следующие вопросы. Гуглить можно в любое время, здесь никто не забивается. Сколько регионов в Гане? А как..

    «Раскрытие математических рассуждений с помощью Microsoft MathPrompter и моделей больших языков»
    TL;DR: MathPrompter от Microsoft показывает, как использовать математические рассуждения с большими языковыми моделями; 4-этапный процесс для улучшения доверия и рассуждений в математических..