1

Strange things happens today when I do things like this:

a = np.array([1, 2, 3])

b = a

b[0] = 0

print a, b

And then the value seems to be passed by reference! The answer becomes:

result: [0 2 3] [0 2 3]

But usually I think the variable in python is passed by value, like this:

a = np.array([1, 2, 3])

b = a

b = np.array([0, 2, 3])

print a, b

And then the answer becomes:

result: [1 2 3] [0 2 3]

But why is that happenning? How do I decide whether the variable is passed through reference or value? Some people said it was because of the mutable object, but I still don't quite get it. So can you explain it for me? Thanks a lot!

Dirk Paul
  • 129
  • 13
  • What's strange about that to you? – vallentin Mar 08 '17 at 16:51
  • Possible duplicate of [How do I pass a variable by reference?](http://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference) – TemporalWolf Mar 08 '17 at 16:52
  • Assignment **never** makes a copy in Python. That's always how it works. Your second example is working *exactly the same* as your first. – juanpa.arrivillaga Mar 08 '17 at 16:58
  • You assigned a new object, `np.array([0, 2, 3])`, to `b` in the second case, instead of changing the original object. More spcifically, if you write `b = None` or `b = 10` in the second case, it will do nothing to `a`, that's reasonable. – zsrkmyn Mar 08 '17 at 16:59
  • Also, this isn't about evaluation strategy, but about how assignment works in Python. Read [Python has names, not variables](http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables). Also, check out [Facts and Myths about Python Names and Values](https://nedbatchelder.com/text/names.html). – juanpa.arrivillaga Mar 08 '17 at 17:04

2 Answers2

3

As it doesn't have anything directly to do with NumPy, let's rewrite it as:

a = [1, 2, 3]

b = a

b = [0, 2, 3]

print a, b

The key thing is that names and values are separate things. So on the first line:

a = [1, 2, 3]

You create a list and assign it to a

Now on the next line you assign a to b. There is still only 1 list, both names simply refer to it.

Next you create a new list and assign it to b. Now b refers to the new list instead of the old list. In turn now only 1 name (a) refers to the other list, instead of 2 names.

Thus if we take the first example, where you do:

b[0] = 0

There both a and b reference the same list, thus the change can be observed from both names, as both names refers to the same list.

vallentin
  • 23,478
  • 6
  • 59
  • 81
1

Variable assignment in Python is always assignment to a reference. In other words, in Python, variables are names, and assigning a variable is declaring a name for something.

a = np.array([1, 2, 3])

b = a

b[0] = 0

print a, b

This means let a be the name for that first array, then let b be a name for a, but a means the first array, so really we're just saying let b also be a name for the first array. Then b[0] = 0 means change the first element of the array. Then when you print a and b, you are printing the same thing twice (the array), because a and b are names for the same thing.

a = np.array([1, 2, 3])

b = a

b = np.array([0, 2, 3])

print a, b

The first two lines are the same as last time. a is a name for the array and so is b. Then b = np.array([0, 2, 3]) means that b is now a name for this new array. So when you print a and b you are printing a, which is still the name for the first array, and b, which is the name for the second array.

Denziloe
  • 7,473
  • 3
  • 24
  • 34