4

私は Python の初心者です。代入演算子を明確に理解できません。たとえば、次のようになります。

list1 = ["Tom", "Sam", "Jim"]
list2 = list1

上記の 2 つのステートメントは 'list1' と 'list2' を にバインドし["Tom", "Sam", "Jim"]ます。問題は、次のような演算子の場合です。

list1[1] = "Sam's sister"、割り当てステートメントもバインディングと見なされる場合、list2[1]それでも「Sam」に関連付けられます。その結果、変更list1は に影響しません。Pythonlist2は反対の出力を提示しますが、別の問題はlist1[1]、 を変数と見なすことができるかどうかです。list1そしてlist2Pythonで。

誰でも何か提案はありますか?

4

4 に答える 4

4

あなたの例では、識別子list1list2は同じ基礎となるオブジェクトへの参照です(同じものの異なる名前です)。

id()同じ基になるオブジェクトが参照されているかどうかを確認するために使用できます。

>>> list1 = ["Tom", "Sam", "Jim"]
>>> list2 = list1
>>> id(list1)
44259368
>>> id(list2)
44259368

定義済みリストのコピーを作成するには、[:]表記法またはdeepcopyマシューが言及したように使用します。これが完了すると、場所/ID が変更されていることがわかります。

>>> list3 = list1[:]
>>> id(list3)
44280208

id コマンドについて:

>>> help(id)
Help on built-in function id in module __builtin__:

id(...)
    id(object) -> integer

    Return the identity of an object.  This is guaranteed to be unique among
    simultaneously existing objects.  (Hint: it's the object's memory address.)
于 2012-10-15T02:55:56.890 に答える
3

そうです、それらは同じではありません。Python ( name = ...) の生の名前への割り当ては、他のものへの割り当てとは異なる操作です。name[0] = ...特に、項目の割り当て ( ) や属性の割り当て ( ) とは異なりますname.attr = ...。それらはすべて等号を使用しますが、後者の 2 つはフック (__setitem__および__setattr__) で操作可能であり、任意のコードを呼び出すことができ、通常はプログラマーの制御下にあります。生の名前への割り当ては、Python プログラマーの制御下にはありません。その動作に影響を与えることはできません。常に右側を左側の名前にバインドするだけです。

これは混乱を招く可能性があります。なぜなら、人々は等号が「割り当て」を行うものであると考えることに慣れているからです。しかし、Python では、どのような操作が行われているのかを理解するために、等号の左側を実際に見て、どのようなものが割り当てられているのかを確認する必要があります。

于 2012-10-15T02:32:02.647 に答える
1

BrenBarn はすべてについて完全に正しいですが、理解しやすいかもしれない別の見方を以下に示します。

最初のステートメントは、これらの値でリストを作成し、list1 がそれ​​を指すようにします。2 番目のステートメントは、list2 が list1 とまったく同じメモリ空間を指すようにします。(これは、2 番目のステートメントの後に両方で id を実行することで確認できます)。

その時点で、list1 と list2 は基本的に両方とも同じ可変リストへの参照です。そのリストを変更すると、list1 と list2 はまだ同じ実際のリストを参照しており、どちらを使用してアクセスしても同じ結果が得られます。

私は最近、関連するトピックについてブログ投稿を行いました。また、Python Conquers the Universe も同様のトピックについて説明しています

于 2012-10-15T02:44:24.383 に答える
0

BrenBam は、何が起こっているのかをよく説明しています。deepcopyそれを回避する方法:

>>> from copy import deepcopy
>>> list1 = ["Tom", "Sam", "Jim"]
>>> list2 = deepcopy(list1)
>>> list1[1] = "Sam's sister"
>>> list1
['Tom', "Sam's sister", 'Jim']
>>> list2
['Tom', 'Sam', 'Jim']

ただし、プログラミング スタイルが優れていれば、実際に使用する必要はほとんどdeepcopyありません。

于 2012-10-15T02:38:48.407 に答える