Ben*_*man 5 python numpy reference function matrix
>>> a = np.arange(9).reshape((3, 3))
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> def sub(a):
... return a[:2, :2]
...
>>> sub(a)
array([[0, 1],
[3, 4]])
>>> sub(a) = np.arange(4).reshape((2, 2))
File "<stdin>", line 1
SyntaxError: cant assign to function call
>>> t = a[:2, :2]
>>> t = np.arange(4).reshape((2, 2))
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> a[:2, :2] = np.arange(4).reshape((2, 2))
>>> a
array([[0, 1, 2],
[2, 3, 5],
[6, 7, 8]])
Run Code Online (Sandbox Code Playgroud)
而且很明显为什么会这样:当我输入时t = ..,我只是'重新链接' t到内存中的其他数据.但问题是:
- 我怎样才能...传递对功能之外的子矩阵的引用?
简而言之,您无法像在 C++ 中那样从 Python 中的函数调用返回左值。在您的情况下,Python 假定您直接将值分配给sub(a),这是一个函数调用,而不是分配给它返回的对象。
当然,您可以使用索引来获取对原始对象的引用,如下所述。这将允许您更改原始矩阵的部分。
- 并且仍然能够更改这个子矩阵值?
您可以更改函数本身内部数组的子矩阵的值,如下所示:
def sub(a):
a[:2, :2] = np.arange(4).reshape((2,2))
return a[:2, :2]
Run Code Online (Sandbox Code Playgroud)
这不仅会return修改子矩阵,还会更改数组本身。
对象是按引用传递的,但它们的引用是按值传递的:
就像Java一样,Python是按值传递的,因此所有对象都作为引用传递到函数中,并且这些引用是按值传递的。
因此,当您索引此数组对象并在函数内修改其值时,您正在修改此引用指向的内存位置的值,但如果您更改引用本身,那么它不会修改原始对象,因为它的引用仅按值传递。
使用索引按值传递对对象的引用:
按照这个解释,您甚至可以更进一步,按值从函数返回对象的引用,并在函数外部使用它修改矩阵:
sub(a)它将按值返回对子矩阵的引用,子矩阵本身就是对按值传递的原始矩阵的引用。x = sub(a)x[:] = np.ones((2,2))这也将修改原始矩阵,a因为您已经修改了内存中所引用的位置的值x。
>>> x = sub(a)
>>> x[:] = np.ones((2,2))
>>> x
array([[1, 1],
[1, 1]])
>>> a
array([[1, 1, 2],
[1, 1, 5],
[6, 7, 8]])
Run Code Online (Sandbox Code Playgroud)
或者,作为快捷方式:
>>> sub(a)[:] = np.ones((2,2))
>>> a
array([[1, 1, 2],
[1, 1, 5],
[6, 7, 8]])
Run Code Online (Sandbox Code Playgroud)更改引用不会更改对象:
但是,现在如果您将变量设置x为np.ones((2,2))则a不会更改,因为通过这样做,您正在更改按值传递的引用本身。
>>> x = 2 # this won't change a because x is a reference passed by value
>>> a
array([[1, 1, 2],
[1, 1, 5],
[6, 7, 8]])
Run Code Online (Sandbox Code Playgroud)