我是Python和Numpy的新手,在将MATLAB程序翻译成Python时遇到了这个问题。
据我所知,下面的代码通过修改全局变量表现异常,即使它不应该。
import numpy as np
A = np.matrix([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
def function(B):
B[1,1] = B[1,1] / 2
return B
C = function(A)
print(A)
输出结果为:
[[0 1 2]
[3 2 5]
[6 7 8]]
该函数将矩阵的中间数除以2并返回它。但它似乎也在改变全球变量。
在这里,问题很容易避免,但我试图理解它为什么会出现。
由于某些原因,如果函数将WHOLE矩阵除以2,则不会发生这种情况。
import numpy as np
A = np.matrix([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
def function(B):
B = B / 2
return B
C = function(A)
print(A)
输出结果为:
[[0 1 2]
[3 4 5]
[6 7 8]]
答案 0 :(得分:2)
在第一种情况下
def function(B):
B[1,1] = B[1,1] / 2
return B
更改名称B
指向的可变对象的特定元素的内容。正如上一个答案所述。
然而,在
def function(B):
B = B / 2
return B
重点是B / 2
是一个新对象。作为输入给出的对象不会改变。
您将其重新分配给本地名称B
这一事实并不重要。它使B
不再指向作为函数输入提供的原始对象,而是指向一个全新的对象实例。该函数返回。
因此,正确地,名称A
指向的对象实例不受影响,即使是可变的。
答案 1 :(得分:1)
与MATLAB相比,Python是一种pass by reference
语言。通常,函数被赋予对每个参数的引用。如果函数然后修改参数,例如B[1,1]=...
,这一变化反映在论证中。
http://www.mathworks.com/matlabcentral/answers/152-can-matlab-pass-by-reference 是对MATLAB通过句柄v。按值传递参数的区别的解释。实际上,Python / numpy通过句柄传递。
根据这个答案,MATLAB中的B(1,1) = B(1,1)/2
会强制复制,因此B
不再与A
共享引用。在Python
中,此类操作会修改调用参数,而不会复制。它发生在函数中并不重要。
答案 2 :(得分:0)
当你有B[1,1] = B[1,1]/2
时,你正在修改一个可变数据结构的元素 - 这会改变数据结构。在B = B / 2
中,您将在本地范围内重新分配B以指向其他内容。退出本地范围时,该更改不会持续存在。