7
myVar = ["jhhj", "hgc"]
myTuple = ([1,2,3], [4,5,6], myVar)
myVar.append('lololol')
print myTuple

構築後に追加することで、このタプルを変更する理由と方法を教えてください。

myVar = "lol"
myTuple = ([1,2,3], [4,5,6], myVar)
myVar = "lolol"
print myTuple

([1,2,3], [4,5,6], "lol")なぜこれが代わりに印刷されるの([1,2,3], [4,5,6], "lolol")ですか?

4

6 に答える 6

7

さて、いくつかの画像で説明してみましょう。

Pythonでは、すべてがオブジェクトです。これらのオブジェクトは変数によって参照されます。リストやタプルなどの一部の種類のオブジェクトは、他のオブジェクトへの参照を格納するだけです。

とはいえ、実行すると

myVar = ["jhhj", "hgc"]
myTuple = ([1,2,3], [4,5,6], myVar)

このシナリオは多かれ少なかれ得られます。

3つのリストを指すタプル。 2つの文字列を指すリスト

各オブジェクトは、ボックス/長方形で表されます。2つの文字列オブジェクト"jhhj""hgc"。また、変数で示されるリストオブジェクトがありますmyVar。このリストオブジェクトは、両方の文字列オブジェクトを指します。myTupleまた、 ;で参照されるタプルオブジェクトがあります。このタプルオブジェクトは、他の2つのリストと。によって参照されるリストを指しますmyVar

実行すると

myVar.append('lololol')

何が起こりますか?さて、リストオブジェクト(偶然にが指しているmyVar)はもう1つの値、文字列オブジェクトを参照し始めます"lololol"

3つのリストを指すタプル。 2つの文字列を指すリスト。 新しい文字列がリストに追加されます

myVarそれでもリストオブジェクトを参照していることに注意してください。何が起こったのかというと、リストオブジェクトが変更されたということです。タプルからまたはタプルからこのリストオブジェクトを見ることができますmyVar。同じ変更で同じオブジェクトが表示されます。

OTOH、実行すると

myVar = "lol"
myTuple = ([1,2,3], [4,5,6], myVar)

あなたはこのようなものを手に入れます:

2つのリストと文字列を指すタプル。これも変数によって示されます

ここmyVarで、文字列オブジェクトをポイントし"lol"、タプルは3番目の位置でそれを参照します。さて、実行すると

myVar = "lolol"

myVar別のオブジェクトを指すようにしているだけです。タプルオブジェクトは"lol"以前と同じようにポイントします。

2つのリストと文字列を指すタプル。これも変数によって示されます。 変数は別の文字列を参照するようになりました。

したがって、新しい値を変数に関連付けると、この変数が指す値が変更されるだけです。変数によって参照される以前の値は引き続き存在し*、それを指す他の変数またはオブジェクトは引き続きそれを指します。属性変数のみが変更されます。

PS:また、私は少し前に漠然と関連した質問に答えました。答えが役立つかもしれません。

*ガベージコレクターによって収集された場合を除きますが、これはもう1つの長い歴史です。

于 2012-06-14T03:36:54.177 に答える
5

Pythonのすべてのものはオブジェクトです。

だからあなたがあなたの元の割り当てをするとき

myVar = "lol"

myVarにオブジェクト「lol」への参照を与えています

次に、タプルを作成します。3番目のスロットのこのタプルには「lol」への参照があります

次に、新しいオブジェクト「lolol」を作成し、myVarにそのオブジェクトへの参照を与えます。タプルは「lol」への元の参照を保持します

于 2012-06-14T02:53:08.753 に答える
1

タプルは不変であるため、そのメンバーの1つを変更する場合は、新しいタプルを作成する必要があります...

于 2012-06-14T02:52:23.357 に答える
1

タプルは不変ですが、次のように連結できます。

var a = (1, 2)
var b = a + (3, 4)
于 2012-06-14T02:55:13.947 に答える
1

どちらの場合も、タプルを作成するときは、その時点であったオブジェクトへの参照をコピーしてmyvarいます。

最初のケースでmyvarは、は可変オブジェクトです。オブジェクトへの参照がタプルに格納された後で、オブジェクトを変更できます。

2番目のケースでmyvarは、は不変の文字列です。オブジェクトを変更することはできませんが、myvarそれ自体が参照するものを変更することはできます。ただし、タプル内に含まれているオブジェクトは変更されません。

于 2012-06-14T03:38:22.693 に答える
1

他の回答には、名前オブジェクトの違いを説明するために、もう一度繰り返すことのない素晴らしい点がいくつかあります。私が欠けていると思うのは、一部のPythonコードが名前を操作しているときと、オブジェクトを操作しているときのスペルです。

ただし、理解する必要がある重要なことは、名前に直接影響するのは代入ステートメント[1]だけであるということです。割り当てステートメントは、別のオブジェクトを指すように名前を再バインドします。のコンテキストで表示される名前は、そのコード行が実行されたときに名前がバインドされているオブジェクトを表す単純なものです。

あなたの例からこの行を見てみましょう:

myTuple = ([1,2,3], [4,5,6], myVar)

myTuple割り当てステートメントの左側にが表示されるので、名前 myTupleはそこで影響を受けているものです。myVar一方、式の中にあるので、オブジェクト myVarがバインドされているのは、名前ではなくmyVar、タプルの3番目の要素です。

したがって、名前 myVarの後で何が起こっても、タプルには何の影響もありません。myVarただし、タプルの3番目の要素が同じオブジェクトを参照している限り、そのオブジェクトを(いずれかmyVarまたはタプルを介して)変更すると、いずれかの参照を介してオブジェクトを表示したときに得られるものに明らかに影響します。


[1]高度な研究の場合defclassステートメントは「代入ステートメント」でもあります(関数またはクラスを作成し、それを名前に割り当てます)。

また、 LHSで現在名前で参照されているオブジェクトのタイプによっては、、など+=の演算子が代入ステートメントである場合とそうでない場合があります。*=

myList = []
myList += ['this calls a method on a list object which mutates it in place; the name is not changed']

myInt = 1
myInt += 10  # This rebinds myInt to refer to a new object 11; the object 1 is not changed
于 2012-06-14T04:31:00.500 に答える