我是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并返回它。但它似乎也在改变全局变量。
在这里,这个问题可以很容易地避免,但我试图理解为什么会出现这个问题。
由于某些原因,如果函数将整个矩阵除以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]]发布于 2015-07-13 05:39:58
在第一种情况下
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所指向的对象实例是不受影响的,即使是可变的。
发布于 2015-07-13 06:03:25
与MATLAB不同,Python是一种pass by reference语言。通常,函数会被赋予对每个参数的引用。如果函数随后修改了一个参数,例如B[1,1]=...,则此更改将反映在参数中。
http://www.mathworks.com/matlabcentral/answers/152-can-matlab-pass-by-reference解释了MATLAB在通过句柄传递参数与通过值传递参数之间的区别。实际上,Python/numpy是通过句柄传递的。
根据这个答案,MATLAB中的B(1,1) = B(1,1)/2会强制复制,这样B就不再与A共享引用。在Python中,这样的操作会修改调用参数,而不会进行复制。它是否出现在函数中并不重要。
发布于 2015-07-13 05:33:56
当您使用B[1,1] = B[1,1]/2时,您正在修改可变数据结构的元素--这会改变数据结构。在B = B / 2中,您正在重新分配本地作用域中的B,以指向其他对象。当您退出本地作用域时,该更改不会持久。
https://stackoverflow.com/questions/31372778
复制相似问题