Why do we have two different behaviors on these np.array?
def pass_by_ref(A: np.array):
A = np.ones((2,2))
return A
def pass_by_ref_sideEffect(A: np.array):
A[0][0] = 2
return A
A = np.zeros((2,2))
B = pass_by_ref(A)
print("A =\n", A)
print("B =\n", B)
C = pass_by_ref_sideEffect(A)
print("A =\n", A)
print("C =\n", C)
output:
A =
[[0. 0.]
[0. 0.]]
B =
[[1. 1.]
[1. 1.]]
A =
[[2. 0.]
[0. 0.]]
C =
[[2. 0.]
[0. 0.]]
Why we have side effect on A after pass_by_ref_sideEffect and not with pass_by_ref?
CodePudding user response:
This has nothing to do with how you are passing in the variable and everything to do with how assignment works. In pass_by_ref()
this line A = np.ones((2,2))
creates a new array and assigns it to the local name A
. The original array object still exists, but A
no longer refers to it. In the other case you are manipulating the original array by assigning to an element of it with A[0][0] = 2
.
If you want to have a side effect in the first case, then assign to a slice of A like this:
def pass_by_ref(A: np.array):
A[:,:] = np.ones((2,2))
return A
A = np.zeros((2,2))
B = pass_by_ref(A)
print(A)
[[1., 1.],
[1., 1.]]
print(B)
[[1., 1.],
[1., 1.]]
Here's an example that demonstrates this without passing variables into functions:
In [1]: import numpy as np
In [2]: A = np.zeros((2,2))
In [3]: B = A
In [4]: B
Out[4]:
array([[0., 0.],
[0., 0.]])
In [5]: A[:,:] = np.ones((2,2))
In [6]: B
Out[6]:
array([[1., 1.],
[1., 1.]])
CodePudding user response:
When Python calls the function, it passes the reference of the object. When you use A[0][0] = 2
for assignment, it will offset according to the address of the object pointed to by variable A
, find the address to be write. But if you use A = np.ones((2, 2))
, a new array will be created and make variable A
points to it.