Рекурсия — почему этот код для печати последовательности чисел не работает

Я прошу прощения за то, что задаю здесь такой тривиальный вопрос для новичков, но каждый раз, когда я делаю два шага вперед в понимании рекурсии, я, кажется, делаю три шага назад. Я не могу понять, почему этот простой код для хранения n чисел в массиве дает пробелы. Я могу заставить его работать, выполнив закомментированную часть, но в верхней части, которая не работает, я предположил, что y и x будут заполнены, когда кадр стека раскручивается, и массив должен возвращать список чисел. Может кто-нибудь объяснить, что не так с моим предположением и как визуализировать рекурсию и как использовать результаты, когда вызовы выполняются рекурсивно и когда возвращаемые значения распространяются обратно в основную функцию?

def nums(n,x):

    if n == 0:
        return n
    else:
         y=(nums(n-1,x))
         x.append(y)    
    return x                # output was all blanks

      #  nums(n-1,x)
      #  x.append(n)
    return x                  # This works

x=[]       
print(nums(7,x))

Вы, кажется, не приняли ни одного ответа ни на один из ваших предыдущих вопросов. Возможно, просмотрите эти старые вопросы и примите ответ, который решил вашу проблему; или, если хотите, опубликуйте свой собственный ответ и примите его. Принятие ответа поможет будущим посетителям отметить вопрос как решенный. См. также помощь. Низкий уровень принятия, вероятно, отпугнет пользователей от того, чтобы тратить свое время на чтение ваших вопросов.

tripleee 10.05.2022 15:33
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
44
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Способ, которым мы обычно учим это с помощью рекурсии, состоит в том, чтобы делать трассировки стека с разными значениями, чтобы продемонстрировать поток.

nums(0, []) => 0 # n.b., this is a scalar, not an array based on the code above
nums(1, []) =>
  y = (nums(0, x)) => 0 (from above) # n.b., this might be interpreted as a tuple since we have surrounded it with parentheses, best to avoid enclosing parentheses if you don't need them
  x.append(y) => x = [ 0 ]
  return x => [ 0 ]

Теперь мы усложняем задачу, потому что x — это list, поэтому возвращается передается по ссылке. Таким образом, для n > 1 мы будем добавлять x к самому себе, что и вызовет проблему.

nums(2, []) =>
  y = nums(1, []) =>
    y = nums(0, []) =>
      y = 0
      x = [ 0 ]
    => [ 0 ]
  x.append(x = [ 0 ]) => yields a circular reference since we are appending x to itself

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


def nums(n):
    if n == 0:
        return [ 0 ]
    return [ n ] + nums(n - 1)

Другие вопросы по теме