2013-03-04 94 views
2

我有下面的簡單的程序中的問題:修改函數中的numpy數組?

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 

彷彿my_array傳遞通過拷貝而不是通過在函數內部參考它打印空數組。如何糾正?

回答

4

np.zeros(0)給你一個空numpy的陣列。現在函數中的引用現在指向一個新的Python列表,但是實際上並沒有修改空的numpy數組,所以這仍然是您要打印的內容。

推薦閱讀this answer來清除一些概念。

+0

對不起,我的錯 – DonCallisto 2013-03-04 15:29:25

+0

不用擔心:) – YXD 2013-03-04 15:30:19

+0

我不明白爲什麼當我打印數組裏面的函數的時候效果不錯,但不是外面的... – Vincent 2013-03-04 15:30:39

4

你可以在這裏使用切片分配就像你的列表:

def func(my_array): 
    my_array[:3] = [1,2,3] 

注意,這仍然需要在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.]) 

你缺少的東西是python如何處理引用。當您輸入my_function時,您可以參考綁定到名稱my_array的原始ndarray對象。但是,只要分配給該名稱的新內容,就會丟失原始引用並將其替換爲對新對象(本例中爲列表)的引用。

注意,具有默認參數,它是一個可變對象可以經常lead to surprises

+0

我不知道是否有一個簡潔的方式來避免':3'。如果輸入數組有10個元素,那麼這個代碼就不會做我懷疑OP會從他的代碼中期望的東西。 – NPE 2013-03-04 15:26:40

+1

這實際上並不奏效 - 試試'a = np.zeros(0)' 和'a [:3] = [1,2,3]' – YXD 2013-03-04 15:28:15

+0

@MrE - 當然。我想我假設OP實際上會通過一個足夠大的參數來處理計算中的RHS。 – mgilson 2013-03-04 15:29:36

7

傳遞引用模型更多地是指針的傳值。所以在你的my_function中,你有一個指向你的原始my_array的指針的副本。如果您要使用該指針直接操作輸入數組,但會進行更改,但是複製指針的重新分配不會影響原始數組。

作爲一個例子:

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

ar = np.zeros(4) 
my_func(ar) 
print ar 

上面的代碼將改變AR的內部值。