如果您是从 C/Java/等语言开始使用 Python。家人,它可能会帮助您停止将a 视为“变量”,而开始将其视为“名称”。
a、b 和 c 不是具有相同值的不同变量;它们是相同值的不同名称。变量有类型、身份、地址和各种类似的东西。
名字没有这些。 值当然可以,而且你可以有很多相同的值的名称。
如果你给 Notorious B.I.G. 一个热狗,* Biggie Smalls 和 Chris Wallace 有一个热狗。如果将a 的第一个元素更改为1,则b 和c 的第一个元素为1。
如果您想知道两个名称是否命名同一个对象,请使用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 函数,它为您提供一个代表对象身份的唯一数字,即使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]的情况完全一样:你有三个名字对应同一个值。
但在这种情况下,值是int,而ints 是不可变的。在任何一种情况下,您都可以将 a 重新绑定到不同的值(例如,a = "Now I'm a string!"),但不会影响原始值,b 和 c 仍将是其名称。不同之处在于,使用列表,您可以将值 [1, 2, 3] 更改为 [1, 2, 3, 4],例如 a.append(4);因为这实际上改变了b 和c 的名称,所以b 现在将变为[1, 2, 3, 4]。无法将值 10 更改为其他值。 10 永远是 10,就像吸血鬼克劳迪娅永远是 5(至少在她被 Kirsten Dunst 取代之前)。
* 警告:不要给臭名昭著的 B.I.G.一个热狗。黑帮说唱僵尸不应该在午夜之后喂食。