1

私は、なぜ次のことが起こっているのか、絶対に唖然とします。

これが私のコードです:


def add_one(array):

    new_array = array
    length = len(array)

    for i in range(length):

        new_array[i] = new_array[i]+1


    return new_array

x = [1,2,3,4,5];
y = add_one(x)

print x

print y

結果は次のとおりです。

[2, 3, 4, 5, 6]

[2, 3, 4, 5, 6]

xが変更された理由がわかりません。

私の推測:どういうわけか、xは関数add_oneのグローバル変数として与えられています。'new_array = array'を含めたので、配列が何らかの形でグローバル変数xである場合、xは変更されません。ただし、「new_array = array」が実行されると、どういうわけかnew_arrayもグローバル変数xになりました。私は問題を起こさなかった関数add_oneの代替バージョンを書きました:


def add_one(array):

    new_array = []
    length = len(array)

    for i in range(length):
        new_array.append(array[i]+1)

ローカル変数(つまり配列)が関数内のインデックスによって編集された場合、その関数の入力として取得されたグローバル変数に対してグローバルになりますか?

何が起こっているのかわかりません。説明をいただければ幸いです。

4

4 に答える 4

6

あなたが言うときnew_array = array、あなたは配列のコピーを作成しているのではなく、単に配列の別の名前を作成しているだけです。どちらの名前も同じアレイに適用されます。

コピーを作成する最も簡単な方法は、スライスを使用することです。new_array = array[:]

于 2011-04-20T21:58:56.043 に答える
4

あいまいなreadonのためにグローバルにされるものはありません。arrayまだ完全に正常なローカル変数です。しかし、Pythonのすべて(少なくともすべての名前)は参照であるため、これは参照です。

  • add_one(x)参照(たとえば、C ++の参照とは異なり、ポインタのようなものです。どちらかがあなたにとって何か意味がある場合)をxに渡します。add_one
  • new_array = arrayその参照をコピーするだけです
  • コピーは発生しません。これらの名前はすべて同じオブジェクトを指しています。

つまり、呼び出し元のまったく同じオブジェクトを変更しarrayてメソッドを呼び出すと、参照します-再割り当て()は、参照のローカルコピーを上書きするだけで、同じオブジェクトを参照する他の変数には影響しません(結局のところ、それはかなり可能です)そのような変数はありません!)が、メンバーまたはアイテムの割り当て(たとえば)は基本的にメソッド呼び出しであり、オブジェクト変更します。add_onexarrayarray = []new_array[i] = ...

一般に、既存のリストから新しいリストを生成する最も簡単な方法は、各要素にいくつかの変更パターンが適用され、オプションでいくつかのフィルタリングがリスト内包表記を使用することです。[x + 1 for x array]この例では。

于 2011-04-20T22:01:23.480 に答える
1

3行目で、yをxに設定します。

new_array = array
于 2011-04-20T21:59:37.107 に答える
0

この行は重要なものです。

new_array = array

新しい変数としてではnew_arrayなく、すでに名前が付いている変数(オブジェクト)の新しい名前として表示する必要がありますarray

于 2011-04-20T21:56:43.833 に答える