我正在尝试了解python中的可变/不可变对象。在下面的示例中,我希望所有id(**)都获得相同的对象id,但#list 4不是。如何解释仅#list 4提供不同的对象ID的原因?谢谢。
# list 1
la = [1,2,3]
print('la=', la, ', id(la)= ',id(la))
# list 2
la[0]=9
print('la=', la, ', id(la)= ',id(la))
# list 3
lb=la
print('lb=', lb, ', id(lb)= ',id(lb))
# list 4
lc=la[:]
print('lc=', lc, ', id(lc)= ',id(lc))
la= [1, 2, 3] , id(la)= 2678849549576
la= [9, 2, 3] , id(la)= 2678849549576
lb= [9, 2, 3] , id(lb)= 2678849549576
lc= [9, 2, 3] , id(lc)= 2678844118664
以这种方式考虑:切片需要是不同的对象,是原始对象的副本:
In [15]: la=[1,2,3]
In [16]: la[:2]
Out[16]: [1, 2]
In [17]: la=[1,2,3]
In [18]: lb=la[:2]
In [19]: lb[0] = 5
In [20]: lb
Out[20]: [5, 2]
In [21]: la
Out[21]: [1, 2, 3]
[la[:]
是切片,尽管以这种形式,它是返回整个列表的切片。
但是切片与元组(这是不可变的类型)的工作方式相同:
In [22]: ta=(1,2,3)
In [23]: ta[:2]
Out[23]: (1, 2)
等
与列表的区别在于您无法执行ta[0] = 5
。这使得元组不可变,并且列表可变。
分配给la
或ta
不会更改任何对象,这些只是对象的名称(别名):
ta=[1,2,3]
ta=4
第二个赋值未更改列表,而是将名称ta
更改为引用整数4
。如果没有其他引用,列表[1,2,3]
将被垃圾收集并销毁。
[:]
语法是copy
的快捷方式,它从原始对象创建一个新的(浅表副本)对象。浅表副本是新的高级对象,因此将仅引用嵌套对象(不创建嵌套对象的新副本)。例子,
copy