Список остается неизменным после изменения элемента - PullRequest
1 голос
/ 10 января 2020

При попытке реализовать алгоритм я не смог заставить списки python мутировать через функцию. После прочтения этой проблемы мне был предложен этот ответ StackOverflow , чтобы использовать [:] для преобразования массива, переданного в функцию argumemt.

Однако, как видно из следующего кода фрагмент, проблема все еще сохраняется при попытке изменить список l. Я ожидаю, что на выходе будет Before: [1,2,3,4] After: [69, 69, 69, 69], но вместо этого я получу исходное значение l, как показано ниже.

def mutate_list(a, b):
    c = [69] * 4
    a[:] = c[:2]  # changed the elements, but array's still unchanged outside function
    b[:] = c[2:]

if __name__ == '__main__':
    l = [1, 2, 3, 4]
    print("Before: {}" .format(l))
    mutate_list(l[:2], l[2:])
    print("After: {}" .format(l))

Выход:

Before: [1, 2, 3, 4]
After : [1, 2, 3, 4]

Любое понимание почему это происходит?

Ответы [ 3 ]

1 голос
/ 10 января 2020

Ошибка в том, что вы передаете не l, а два его фрагмента. Вы должны изменить его, например:

def mutate_list(a):
    c = [69] * 4
    a[:2] = c[:2]
    a[2:] = c[2:]

if __name__ == '__main__':
    l = [1, 2, 3, 4]
    print("Before: {}" .format(l))
    mutate_list(l)
    print("After: {}" .format(l))
0 голосов
/ 15 января 2020

Как отмечали другие, проблема возникла из-за того, что параметры функции были срезами исходного массива и, как таковые, параметры передавались по значению (а не по ссылке).

Согласно предложению @Selcuk, правильным способом выполнения такой операции было бы передать исходный массив вместе с его индексами в функцию, а затем выполнить любое разбиение внутри функции.

ПРИМЕЧАНИЕ. Эта концепция пригодится для (рекурсивных) алгоритмов «разделяй и властвуй», где подрешетки должны быть видоизменены и объединены для формирования решения.

0 голосов
/ 10 января 2020
  1. все дело в области видимости, концепция изменчивости применима к списку, но не для ссылки на переменную.

Переменные a, b являются локальными переменными, поэтому область действия переменной будет всегда функционируйте сферу.

Выполненные вами операции:

a [:] = c [: 2]

b [:] = c [2:]

Примечание: a и b теперь являются списком, поэтому вы получите следующие выходные данные в функции:

[69,69], [69,69]

но если вы используете оператор +, который используется для добавления операций, то выход будет таким:

[69,69,69,69]

Теперь, что бы я ни говорил вам, это будет локальный scope, если вы хотите, чтобы список был изменяемым во всей программе, вы должны указать область списка как глобальную внутреннюю функцию, и в этой переменной вы можете вносить изменения. в этом случае вам также не нужно передавать какие-либо аргументы:

def mutate_list ():

global l # telling python to use this global variable in a local function

c = [69] * 4

l=c      # assigning new values to actual list i.e l

Теперь перед выводом будет [1,2,3,4]

и после будет [69,69,69,69]

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