Почему мои переменные python действуют глобально во время рекурсии? - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть рекурсивная функция, которая не работает так, как я хочу.Внутри функции у меня есть переменная sum.Я хочу, чтобы переменная была локальной / другой для каждого вызова функции, чтобы итоговая сумма стала суммой всех предыдущих вызовов функций.Однако кажется, что переменная действует глобально, поэтому каждый раз, когда вызывается функция, переменная суммы устанавливается в 0, и это то, что возвращается в конце.У меня та же проблема со списком: для каждого вызова функции элемент удаляется из my_list во всех различных рекурсивных фреймах, а не только в локальный фрейм, как я хочу.Это то, как переменные должны работать во время рекурсии в Python?Если это так, как я могу изменить код, чтобы он работал так, как я хочу?

Кстати, цель функции - выяснить, существует ли подмножество списка, который добавляетдо числа n, но это не очень важно для понимания проблемы, с которой я столкнулся.

Я искал похожие посты и нашел кого-то, кто утверждал, что вы не вызываете рекурсию, если не используете returnоператор для возврата функции следующим образом:

return f (n - x, remove (list, x))

Однако, если это так, я не вижу, как я могуоба возвращают функцию и одновременно добавляют значение к сумме.

list1 = [3, 5, 1, 2, 5, 3, 4]

# removes an element from the list, and returns the result
def remove(list_, x):
    list_.remove(x)
    return list_

# recursive function
# should return 1 or more if there exists a combination of numbers in the list
# that add up to the number n
def f(n, my_list):
    sum = 0

    if n == 0:
        return 1
    if len(my_list) == 0:
        return 0
    for x in my_list:
        sum += f(n - x, remove(my_list, x))

    return sum


print(f(15, list1))

Существует подмножество списка, которое добавляет до 15: например (5, 1, 5, 4),поэтому вывод должен быть не менее 1, но из-за того, что переменные действуют глобально, выход всегда равен 0.

Ответы [ 3 ]

1 голос
/ 17 апреля 2019

Создается только один объект списка, поэтому, когда элементы удаляются, они удаляются повсеместно.Вам нужно скопировать список, прежде чем передавать его вниз.Попробуйте это:

list1 = [3, 5, 1, 2, 5, 3, 4]

# removes an element from the list, and returns the result
def remove(list_, x):
    list_.remove(x)
    return list_

# recursive function
# should return 1 or more if there exists a combination of numbers in the list
# that add up to the number n
def f(n, my_list):
    sum = 0

    if n == 0:
        return 1
    if len(my_list) == 0:
        return 0
    for x in my_list:
        sum += f(n - x, remove(list(my_list), x))

    return sum


print(f(15, list1))
0 голосов
/ 17 апреля 2019

sum является int; это неизменно - вы получаете локальную переменную для каждой записи в подпрограмме.

Однако, my_list является изменяемым параметром функции; все вызовы имеют один и тот же объект. Вместо передачи списка, передайте копию усеченного списка. Вы можете сделать это легче с нарезкой. Попробуйте что-то вроде решений, уже доступных онлайн для решения этой проблемы: на каждом шаге рекурсии продвигайтесь в одной ветви, включая ведущий элемент; продвигайся в другом без этого

def f(n, my_list):
    if n == 0:
        return True
    if len(my_list) == 0:
        return False
    if f(n, my_list[1:]):
        return True
    if f(n - my_list[0], my_list[1:])
        return True

    return False
0 голосов
/ 17 апреля 2019
list1 = [3, 5, 1, 2, 5, 3, 4]

# removes an element from the list, and returns the result
def remove(list_, x):
    del list_[x]
    return list_

# recursive function
# should return 1 or more if there exists a combination of numbers in the list
# that add up to the number n
def f(n, my_list, total):
    if n == 0:
        return 0
    if len(my_list) == 0:
        return total
    else:
        total += my_list[0]

    return f(n - 1, remove(my_list, 0), total)



print(f(15, list1, 0))

Ваш код не работает с рекурсивным алгоритмом, я обновил код как рекурсивный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...