修改函数内的numpy数组?

Vin*_*ent 3 python arrays numpy pass-by-reference

我对下面的简单程序有疑问:

def my_function(my_array = np.zeros(0)):
    my_array = [1, 2, 3]

my_array = np.zeros(0)
my_function(my_array)
print my_array
Run Code Online (Sandbox Code Playgroud)

它打印一个空数组,好像my_array是通过复制传递而不是通过函数内部的引用传递.怎么纠正?

Ram*_*gil 9

传递引用模型更像是指针的传值.因此,在my_function中,您有一个指向原始my_array的指针的副本.如果您要使用该指针直接操作输入数组,这将导致更改,但重新分配复制的指针不会影响原始数组.

举个例子:

def my_func(a):
    a[1] = 2.0

ar = np.zeros(4)
my_func(ar)
print ar
Run Code Online (Sandbox Code Playgroud)

上面的代码将改变ar的内部值.


mgi*_*son 7

您可以在这里使用切片分配,就像使用列表一样:

def func(my_array):
    my_array[:3] = [1,2,3]
Run Code Online (Sandbox Code Playgroud)

请注意,这仍然要求my_array其中至少有 3 个元素...用法示例:

>>> def func(my_array):
...     my_array[:3] = [1,2,3]
... 
>>> a = np.zeros(4)
>>> a
array([ 0.,  0.,  0.,  0.])
>>> func(a)
>>> a
array([ 1.,  2.,  3.,  0.])
Run Code Online (Sandbox Code Playgroud)

你缺少的是 python 如何处理引用。当您输入时my_function,您将获得对绑定到该名称的原始 ndarray 对象的引用my_array。但是,一旦您为该名称分配了新内容,您就会丢失原始引用,并将其替换为对新对象(在本例中为列表)的引用。

请注意,具有可变对象的默认参数通常会导致意外


YXD*_*YXD 6

np.zeros(0)给你一个空的 numpy 数组。函数内的引用现在指向一个新的 Python 列表,但您实际上尚未修改空的 numpy 数组,因此这仍然是您要打印的内容。

建议阅读此答案以澄清一些概念。