2

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.

4
  • Possibly a duplicate, definitely helpful: stackoverflow.com/questions/986006/… Commented Oct 3, 2018 at 14:30
  • 1
    Welcome to Python. As you already noticed, not all languages work the same way, so while they usually have common concepts (variables, functions, iterations, conditionnals etc), you'll find out that the implementation of those concepts can be widly different from one language to another, so do not assume that a superficial similarity imply a similar behaviour - IOW, take time to learn the new language without preconception and you'll save yourself a lot of time, pain and frustration. Commented Oct 3, 2018 at 14:49
  • Possible duplicate of stackoverflow.com/questions/22054698/… Commented Oct 3, 2018 at 15:06
  • Possible duplicate of stackoverflow.com/questions/18949904/… Commented Oct 3, 2018 at 15:09

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.