2012-07-20 40 views
35

我碰到一個事實,即numpy陣列通過引用在多個地方通過,但後來當我執行下面的代碼,爲什麼會出現我使用的foo行爲和barnumpy數組是否通過引用傳遞?

import numpy as np 

def foo(arr): 
    arr = arr - 3 

def bar(arr): 
    arr -= 3 

a = np.array([3, 4, 5]) 
foo(a) 
print a # prints [3, 4, 5] 

bar(a) 
print a # prints [0, 1, 2] 

之間的差異來python 2.7和numpy版本1.6.1

+1

相關:http://stackoverflow.com/q/9047111/166749 – 2012-07-20 19:58:45

+0

這個東西Python調用「引用」與傳遞引用無關,這就是爲什麼。 – delnan 2012-07-20 20:06:06

回答

46

在Python中,all variable names are references to values

Python在評估任務時,the right-hand side is evaluated before the left-hand sidearr - 3創建一個新的數組;它不會在原地修改arr

arr = arr - 3使得本地變量arr引用這個新數組。它不會修改arr最初引用的值,該值已傳遞到foo。變量名稱arr只是綁定到新陣列,arr - 3。此外,arrfoo函數範圍內的局部變量名稱。一旦foo函數完成,沒有更多的參考arr和Python可以自由垃圾收集它引用的值。 As Reti43 points out,爲了arr的價值影響afoo必須返回arra必須分配給該值:

def foo(arr): 
    arr = arr - 3 
    return arr 
    # or simply combine both lines into `return arr - 3` 

a = foo(a) 

相比之下,arr -= 3,其中Python的轉化爲對__iadd__ special method一個電話,並修改該陣列在原地由arr引用。

+6

這是一種,不直觀的... – Mehdi 2015-12-14 14:19:08

+0

因此,爲了'foo()'有效果,它需要返回'arr',並在代碼中運行它爲'a = foo(a) 。 – Reti43 2015-12-14 17:46:32

+0

等等,對象是通過引用python中的函數傳遞的......? – 2017-07-11 01:09:11

8

第一個函數計算(arr - 3),然後分配本地名稱arr到它,這不會影響通過陣列的數據。我的猜測是,在第二個功能,np.array覆蓋-=運營商,並在地方上工作陣列數據。