In Python, any value passed to a function is passed by object reference. So, in the first case, where you pass a number to your function, var
is set to a reference to the object that reresents the number 1
. In Python, even numbers are objects. To icrement var
in this case actually means to set it with a reference to the object that represents the number 1+1
, which is the object that represents 2
. Note that object that represents the number 1
is not changed. Within the function, it is replaced.
When you pass a numpy array to your function it is likewise passed in by object reference. Hence, var
now holds a reference to your array a
. Incrementing an array by arr += 1
means to add 1
to each of its elements. Hence, the actual content of the object that var
references has to change. However, var
still references the same object are incrementation.
Take a look at the following code:
import numpy as np
def func(vals):
print('Before inc: ', id(vals))
vals += 1
print('After inc: ', id(vals))
When you pass in a number literal, vals
is set to a reference of the object representing the respective number. This object has a unique id, which you can return using the id
function. After incrementation, vals
is a reference to the object representing a number which is one greater the first one. You can verify that by calling id
again after incrementation. So, the output of the above function is something like:
Before inc: 4351114480
After inc: 4351114512
Note that there are two different objects. When now pass in an numpy array like, the resulting ids are the same:
a = np.zeros(3)
func(a)
Before inc: 4496241408
After inc: 4496241408
If you want to modify an array inside of a function and don't want that the apply changes take effect outside of the function, you have to copy your array:
def func(vals):
_vals = vals.copy()
# doing stuff with `_vals` won't change the array passed to `vals`