有什么不同? numpy.array 绕过 ref
What is the difference? numpy.array pass by ref
为什么我们在这些 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)
输出:
A =
[[0. 0.]
[0. 0.]]
B =
[[1. 1.]
[1. 1.]]
A =
[[2. 0.]
[0. 0.]]
C =
[[2. 0.]
[0. 0.]]
为什么我们在 pass_by_ref_sideEffect 之后对 A 产生副作用而不是 pass_by_ref?
这与您传递变量的方式无关,而与赋值的工作方式有关。在 pass_by_ref()
中,这一行 A = np.ones((2,2))
创建了一个新数组并将其分配给本地名称 A
。原来的数组对象仍然存在,但A
不再引用它。在另一种情况下,您通过使用 A[0][0] = 2
.
分配给它的一个元素来操纵原始数组
如果你想在第一种情况下产生副作用,那么像这样分配给 A 的一片:
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.]]
下面是一个示例,在不将变量传递给函数的情况下演示了这一点:
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.]])
当Python调用函数时,传递的是对象的引用。使用A[0][0] = 2
赋值时,会根据变量A
指向的对象地址进行偏移,找到要写入的地址。但是如果你使用A = np.ones((2, 2))
,一个新的数组会被创建并使变量A
指向它。
为什么我们在这些 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)
输出:
A =
[[0. 0.]
[0. 0.]]
B =
[[1. 1.]
[1. 1.]]
A =
[[2. 0.]
[0. 0.]]
C =
[[2. 0.]
[0. 0.]]
为什么我们在 pass_by_ref_sideEffect 之后对 A 产生副作用而不是 pass_by_ref?
这与您传递变量的方式无关,而与赋值的工作方式有关。在 pass_by_ref()
中,这一行 A = np.ones((2,2))
创建了一个新数组并将其分配给本地名称 A
。原来的数组对象仍然存在,但A
不再引用它。在另一种情况下,您通过使用 A[0][0] = 2
.
如果你想在第一种情况下产生副作用,那么像这样分配给 A 的一片:
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.]]
下面是一个示例,在不将变量传递给函数的情况下演示了这一点:
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.]])
当Python调用函数时,传递的是对象的引用。使用A[0][0] = 2
赋值时,会根据变量A
指向的对象地址进行偏移,找到要写入的地址。但是如果你使用A = np.ones((2, 2))
,一个新的数组会被创建并使变量A
指向它。