Reputation: 60371
I have a problem with the simple program below :
def my_function(my_array = np.zeros(0)):
my_array = [1, 2, 3]
my_array = np.zeros(0)
my_function(my_array)
print my_array
It prints an empty array as if my_array
was passed by copy and not by reference inside the function. How to correct that ?
Upvotes: 6
Views: 28674
Reputation: 32511
np.zeros(0)
gives you an empty numpy array. The reference inside your function now points to a new Python list but you haven't actually modified your empty numpy array, so that's still what you're printing out.
Recommend to read this answer to clear up some concepts.
Upvotes: 6
Reputation: 17933
The pass-by-reference model is more of a pass-by-value of a pointer. So inside your my_function you have a copy of a pointer to your original my_array. If you were to use that pointer to manipulate the inputed array directly that would make a change, but a re-assignment of the copied pointer won't affect the original array.
As an example:
def my_func(a):
a[1] = 2.0
ar = np.zeros(4)
my_func(ar)
print ar
The above code will change the internal value of ar.
Upvotes: 18
Reputation: 309881
You can use slice assignment here just like you would a list:
def func(my_array):
my_array[:3] = [1,2,3]
Note that this still requires that my_array
has at least 3 elements in it ... Example usage:
>>> def func(my_array):
... my_array[:3] = [1,2,3]
...
>>> a = np.zeros(4)
>>> a
array([ 0., 0., 0., 0.])
>>> func(a)
>>> a
array([ 1., 2., 3., 0.])
The thing you're missing is how python deals with references. When you enter my_function
, you have a reference to the original ndarray object bound to the name my_array
. However, as soon as you assign something new to that name, you lose your original reference and replace it with a reference to a new object (in this case, a list).
Note that having a default argument which is a mutable object can often lead to surprises
Upvotes: 9