2012-07-20 15 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

Related:http://stackoverflow.com/q/9047111/166749 –

+0

これはPythonが "参照"と呼ぶことは、参照渡しとは関係がないためです。 – delnan

答えて

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がこの新しい配列を参照するようにします。 fooに渡された元々arrで参照されていた値は変更されません。変数名arrは、単に新しい配列arr - 3にバインドされます。また、arrは、foo機能の範囲内のローカル変数名です。 foo関数が完了すると、arrへの参照はなくなり、Pythonは参照する値を自由にガベージコレクションします。 As Reti43 points outaに影響を与えるarrの値のために、fooarr返さなければならないとaは、その値に割り当てる必要があります。これとは対照的に

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

+0

したがって、 'foo()'が効果を出すためには 'arr'を返す必要があり、コードでは' a = foo(a) ' 。 – Reti43

+0

オブジェクトはPythonの関数への参照によって渡されますか? –

8

最初の関数は、ローカル名を割り当て、(arr - 3)を算出し、渡された配列データには影響を与えません。私の推測では、第二の機能では、np.array-=演算子をオーバーライドすることで、上の所定の位置に動作し、それにarr、配列データ

関連する問題