nish-ant
nish-ant

Reputation: 119

Assignment of variables inside function changes assignment outside - Python

I moved from using Matlab to Python and the variable assignment while using functions is confusing me.

I have a code as follows:

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)

The first print statement gives [1, 1, 1] [1, 2, 1], while

the second one gives [1, 2, 1] [1, 2, 1].

I had a understanding (coming from Matlab) that the operations on a variable within a function are local. But here, if I don't make a copy of the variable inside a function, the values change outside the function as well. It's almost as if the variable is defined as global.

It will be very helpful if someone can explain how the variables are allocated differently in both the methods and what are the best practices if one wants to send a variable to the function without affecting it's value outside the function? Thanks.

Upvotes: 2

Views: 2268

Answers (2)

Victor Domingos
Victor Domingos

Reputation: 1083

Let's look at your code, but first, we will mode the function declarations to the top, so that the order of execution becomes clearer.

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)

Basically if you just assign another variable name to a list, you are giving two names to the same object, so any changes in the contents may affect both "lists". When you use y = x[:]you are in fact creating a new copy of the x list in memory, through list slicing, and assigning the new variable name y to that new copy of the list.

Upvotes: 2

timgeb
timgeb

Reputation: 78690

Argument passing is done by assignment. In changes, the first thing that happens implicitly is
x = a when you call changes(a). Since assingment NEVER copies data you mutate a.

In keeps you are not mutating the argument list because x[:] is creating a (shallow) copy which then the name y is assigned to.

I highly recommend watching Facts and Myths about Python names and values.

Upvotes: 3

Related Questions