这里涉及到 Python 的可变对象和不可变对象赋值操作的区别。
可变对象比如:列表、字典等,其内部值可以增删更改;
不可变对象比如:元组、字符串,值一旦形成,便不可更改。
你的示例 1 实际上是对 “a 列表的值” 进行浅复制,而对于所有的可变对象而言,不管所赋的值的大小,赋值操作都会建立新的 ID,以防止多个对象共用一个值 ID 导致的对某个对象值进行更改而影响其他对象的值的情况发生。
a = [1, 2, 3]
b = a
c = a[:]
id(a)
Out[4]: 2618569309704
id(b)
Out[5]: 2618569309704
id(c)
Out[6]: 2618569309640
如上, b 和 c 的 ID 是不一样的,因为 b = a 是拷贝 a,b = a[:] 是拷贝 a 的值,对于可变对象而言,这两者含义是不同的。
而你的示例 2 则是对不可变对象进行赋值操作。由于不可变对象值不可改变,因此 b = a[:] b = a 本质上不存在如上的区别,也就是都是对值 ID 进行拷贝,因此 你的 a/b 的 ID 是相同的。
但是要注意对不可变对象进行赋值操作,解释器可能有一定的优化而不会像对可变对象那样每次都重新建立一个ID,具体来说,对于值比较小的不可变对象进行赋值,解释器一般不会重新开辟新的id,而对值较大的不可变对象进行赋值,则id必须重建:
a = 1
b = 1
id(a)
Out[13]: 1824648976
id(b)
Out[14]: 1824648976
c = 123456789
d = 123456789
id(c)
Out[17]: 2618567010576
id(d)
Out[18]: 2618567009872
如上,a b 值相等且比较小,因此 a b 的id 一样,但 c d 值比较大,而 值 id 就不同。这样做的目的是为了最大限度的提高效能。