69

配列が複数の場所で参照渡しされているという事実に遭遇しましたが、次のコードを実行すると、とnumpyの動作に違いがあるのはなぜですかfoobar

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を使用しています

4

3 に答える 3

84

Python では、すべての変数名は値への参照です

Python が代入を評価するとき、右側が左側より先に評価されます。arr - 3新しい配列を作成します。インプレースで変更されませんarr

arr = arr - 3ローカル変数がarrこの新しい配列を参照するようにします。arrに渡されたによって最初に参照された値は変更されませんfoo。変数名arrは、単に新しい配列 にバインドされarr - 3ます。また、関数arrのスコープ内のローカル変数名です。関数が完了すると、それ以上の参照はなくなりfoo、Python は参照する値を自由にガベージ コレクションできます。Reti43 が指摘しているように、の値が に影響を与えるためには、が返され、その値に割り当てられる必要があります。fooarrarrafooarra

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

a = foo(a)

対照的に、Python が特別なメソッドarr -= 3の呼び出しに変換する は、インプレースで参照される配列を変更します。__iadd__arr

于 2012-07-20T19:34:57.560 に答える
9

最初の関数は を計算し(arr - 3)、それにローカル名を割り当てarrます。これは、渡された配列データには影響しません。私の推測では、2 番目の関数では、演算子をnp.arrayオーバーライドし、配列データを適切に操作します。-=

于 2012-07-20T19:35:38.420 に答える