Назначение переменных внутри функции изменяет назначение снаружи - Python - PullRequest
0 голосов
/ 03 октября 2018

Я перешел с использования Matlab на Python, и назначение переменных при использовании функций сбивает меня с толку.

У меня есть следующий код:

a = [1,1,1]

def keeps(x):
    y = x[:]
    y[1] = 2
    return y

def changes(x):
    y = x
    y[1] = 2
    return y

aout = keeps(a)
print(a, aout)

aout = changes(a)
print(a, aout)

Первый оператор печати дает [1, 1, 1] [1, 2, 1], в то время как

второй дает [1, 2, 1] [1, 2, 1].

Я понял (исходя из Matlab), что операции с переменной внутри функции являются локальными.Но здесь, если я не сделаю копию переменной внутри функции, значения также изменятся и вне функции.Это почти как если бы переменная была определена как global.

Будет ли очень полезно, если кто-то сможет объяснить, как переменные распределяются по-разному в обоих методах, и каковы лучшие практики, если кто-то хочет отправить переменную в функцию, не затрагивая ее значение вне функции?Спасибо.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Давайте посмотрим на ваш код, но сначала мы смоделируем объявления функций сверху, чтобы порядок выполнения стал более понятным.

def keeps(x):
    y = x[:]  #Here you are creating a modifiable copy of the original x list and referencing it with y
    y[1] = 2
    return y

def changes(x):
    y = x  # Here you are just referencing x itself with a new name y
    y[1] = 2
    return y

a = [1,1,1]

aout = keeps(a)
print(a, aout)

aout = changes(a)
print(a, aout)

В основном, если вы просто назначаете другое имя переменной дляlist, вы даете два имени одному и тому же объекту, поэтому любые изменения содержимого могут повлиять на оба «списка».Когда вы используете y = x[:], вы фактически создаете новую копию списка x в памяти, разрезая список и присваивая имя новой переменной y этой новой копии списка.

0 голосов
/ 03 октября 2018

Передача аргумента осуществляется по заданию.В changes первое, что происходит неявно, это
x = a, когда вы звоните changes(a).Поскольку assingment НИКОГДА не копирует данные , вы мутируете a.

В keeps вы не изменяете список аргументов, потому что x[:] создает (мелкую) копию, которая затем называется y присвоено.

Я настоятельно рекомендую посмотреть Факты и мифы об именах и значениях Python .

...