回答:
C / Java /その他の言語からPythonにアクセスする場合。家族、それはあなたがa
「変数」として考えるのをやめ、それを「名前」として考えるのを始めるのを助けるかもしれません。
a
、b
、とc
等しい値を持つ異なる変数ではありません。それらは同じ同一の値に対して異なる名前です。変数には、タイプ、ID、アドレス、およびそのようなあらゆる種類のものがあります。
名前にはそれがありません。もちろん値はあり、同じ値に多くの名前を付けることができます。
Notorious B.I.G.
ホットドッグ* を与えて、ホットドッグBiggie Smalls
をChris Wallace
持っている場合。の最初の要素a
を1に変更するb
と、およびの最初の要素c
は1になります。
2つの名前が同じオブジェクトの名前であるかどうかを知りたい場合は、is
演算子を使用します。
>>> a=b=c=[0,3,5]
>>> a is b
True
次に尋ねます:
これと何が違うの?
d=e=f=3
e=4
print('f:',f)
print('e:',e)
ここでは、名前e
を値に再バインドしています4
。これは、名前には影響しませんd
し、f
どのような方法インチ
以前のバージョンではa[0]
、ではなくに割り当てていましたa
。つまり、の観点からa[0]
はを再バインドしていますa[0]
が、の観点からはa
インプレースで変更しています。
このid
関数を使用すると、オブジェクトのIDを表す一意の番号is
が得られ、助けにならない場合でも、どのオブジェクトであるかを正確に確認できます。
>>> a=b=c=[0,3,5]
>>> id(a)
4473392520
>>> id(b)
4473392520
>>> id(a[0])
4297261120
>>> id(b[0])
4297261120
>>> a[0] = 1
>>> id(a)
4473392520
>>> id(b)
4473392520
>>> id(a[0])
4297261216
>>> id(b[0])
4297261216
a[0]
が4297261120から4297261216に変更されていることに注意してください。これは、別の値の名前になっています。そしてb[0]
今では、同じ新しい値の名前にもなっています。だa
とb
まだ同じオブジェクトを命名しています。
内部では、a[0]=1
実際にリストオブジェクトのメソッドを呼び出しています。(これはと同等a.__setitem__(0, 1)
です。)したがって、実際には何も再バインドしていません。を呼び出すようなものmy_object.set_something(1)
です。確かに、オブジェクトがこのメソッドを実装するためにインスタンス属性を再バインドしている可能性がありますが、それは重要ではありません。重要なのは、何も割り当てず、オブジェクトを変更することだけです。そして、それはと同じa[0]=1
です。
user570826が尋ねた:
もし私たちが持っているとしたら、
a = b = c = 10
これはまったく同じ状況a = b = c = [1, 2, 3]
です。同じ値に3つの名前があります。
ただし、この場合、値はint
で、int
sは不変です。どちらの場合も、あなたは再バインドすることができますa
(例えば、異なる値にa = "Now I'm a string!"
)が、元の値には影響しません、これb
とc
はまだの名前になります。違いはリストで、あなたが値を変更することができるということである[1, 2, 3]
に[1, 2, 3, 4]
行うことによって、例えば、a.append(4)
; そのため、実際にその値を変更することだb
とc
、のための名前であるb
今、bのだろう[1, 2, 3, 4]
。値10
を他の値に変更する方法はありません。10
クラウディアと同様に、吸血鬼は永遠に5です(少なくとも彼女がキルスティンダンストに置き換えられるまで)。
*警告:Notorious BIGにホットドッグを与えないでください。ギャングスタラップゾンビは、深夜以降は餌を与えないでください。
have, a = b = c = 10;
がbの値を更新しようとすると、それは他の何かに影響しますか?私は彼らのIDが同じであることを確認しましたが?
10
不変です。つまり、値を更新する方法がないため、質問は意味がありません。b
別の値をポイントすることもできますが、そうしても、元の値をポイントしているa
およびc
には影響しません。リストの違いは、それらが変更可能であることです。たとえば、append
リストやlst[0] = 3
に変更できます。これにより、値が更新され、その値のすべての名前で表示されます。
咳咳
>>> a,b,c = (1,2,3)
>>> a
1
>>> b
2
>>> c
3
>>> a,b,c = ({'test':'a'},{'test':'b'},{'test':'c'})
>>> a
{'test': 'a'}
>>> b
{'test': 'b'}
>>> c
{'test': 'c'}
>>>
a,b,c = 1,2,3
、ブラケットがなくてもPython 2または3で機能します。
はい、それは予想される動作です。a、b、cはすべて同じリストのラベルとして設定されます。3つの異なるリストが必要な場合は、それらを個別に割り当てる必要があります。明示的なリストを繰り返すか、リストをコピーする多くの方法のいずれかを使用できます。
b = a[:] # this does a shallow copy, which is good enough for this case
import copy
c = copy.deepcopy(a) # this does a deep copy, which matters if the list contains mutable objects
Pythonの代入ステートメントはオブジェクトをコピーしません-それらは名前をオブジェクトにバインドし、オブジェクトは設定した数のラベルを持つことができます。最初の編集でa [0]を変更すると、a、b、cがすべて参照する単一のリストの1つの要素が更新されます。2番目のeの変更では、eを別のオブジェクトのラベルに切り替えます(3ではなく4)。
Pythonでは、すべてがオブジェクトであり、「単純な」変数タイプ(int、floatなど)でもあります。
変数の値を変更すると、実際にはそのポインターが変更されます。2つの変数を比較すると、それらのポインターが比較されます。(明確にするために、ポインターは、変数が格納されている物理コンピューターメモリ内のアドレスです)。
その結果、内部変数の値を変更すると、メモリ内の値が変更され、このアドレスを指すすべての変数に影響します。
あなたの例では、あなたがするとき:
a = b = 5
これは、aとbが値5を含むメモリ内の同じアドレスを指していることを意味します。
a = 6
aは6を含む別のメモリロケーションを指し、bは5を含むメモリアドレスを指すため、bには影響しません。
しかし、あなたがするとき:
a = b = [1,2,3]
aとbも同じ場所を指していますが、違いは、リストの値の1つを変更した場合です。
a[0] = 2
これは、aが指すメモリの値を変更しますが、aは引き続きbと同じアドレスを指しているため、bも変更されます。
PyObject
です。これは、PyPyやJythonなどの他の実装では当てはまりません。(実際、それらの実装が記述されている言語にはポインターさえないため、それがどのように真実であるかさえも明確ではありません。)
を使用id(name)
して、2つの名前が同じオブジェクトを表すかどうかを確認できます。
>>> a = b = c = [0, 3, 5]
>>> print(id(a), id(b), id(c))
46268488 46268488 46268488
リストは変更可能です。つまり、新しいオブジェクトを作成しなくても、値を変更できます。ただし、値の変更方法によって異なります。
>>> a[0] = 1
>>> print(id(a), id(b), id(c))
46268488 46268488 46268488
>>> print(a, b, c)
[1, 3, 5] [1, 3, 5] [1, 3, 5]
新しいリストをに割り当てると、a
そのIDが変更されるため、b
およびc
の値には影響しません。
>>> a = [1, 8, 5]
>>> print(id(a), id(b), id(c))
139423880 46268488 46268488
>>> print(a, b, c)
[1, 8, 5] [1, 3, 5] [1, 3, 5]
整数は不変なので、新しいオブジェクトを作成しないと値を変更できません。
>>> x = y = z = 1
>>> print(id(x), id(y), id(z))
507081216 507081216 507081216
>>> x = 2
>>> print(id(x), id(y), id(z))
507081248 507081216 507081216
>>> print(x, y, z)
2 1 1
id
は必ずしもメモリの場所ではありません。ドキュメントは言う、これは「このオブジェクトの有効期間は一意かつ一定であることが保証されているアイデンティティ...整数を...。」を返します CPythonはメモリアドレスをとして使用しますid
が、他のPython実装では使用しない場合があります。たとえば、PyPyはそうではありません。また、「2つの変数が同じメモリ位置を指す」と言っても、それをCスタイルで理解している人には誤解を招く恐れがあります。「同じオブジェクトの2つの名前」の方が正確であり、誤解を招きにくい。
私が必要とすることを行うコードは次のようになります:
# test
aux=[[0 for n in range(3)] for i in range(4)]
print('aux:',aux)
# initialization
a,b,c,d=[[0 for n in range(3)] for i in range(4)]
# changing values
a[0]=1
d[2]=5
print('a:',a)
print('b:',b)
print('c:',c)
print('d:',d)
結果:
('aux:', [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]])
('a:', [1, 0, 0])
('b:', [0, 0, 0])
('c:', [0, 0, 0])
('d:', [0, 0, 5])
a
、b
とc,
(この場合はリスト)と同じ値にすべてのポイントに、またはあなたがしたいですかa=0
、b=3
とc=5
。その場合、あなたは欲しいa,b,c = [0,3,5]
か、単にa,b,c = 0,3,5
。