6

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 ?

3 Answers 3

18

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.

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

Comments

9

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

3 Comments

I wonder if there's a neat way to avoid the :3. If the input array had, say, ten elements, then this code would not do what I suspect the OP would expect from his code.
This doesn't actually work - try a = np.zeros(0) and a[:3] = [1,2,3]
@MrE -- Sure. I suppose I'm assuming that OP is actually going to pass in an argument that is large enough to handle the RHS in the calculation.
6

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.

2 Comments

I do not understand why when I print the array inside the function it works well, but not outside...
You should read the first answer here stackoverflow.com/questions/986006/…

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.