以不可变对象为元素的列表

a=[1,2]
b=a*3
#则b为
[1,2,1,2,1,2]

以可变对象为元素的列表

#如列表以列表为元素
a=[[1]]
b=a*3
#则b为
[[1],[1],[1]]
#不过有趣的是
id(b[0])==id(b[1])==id(b[2])
#也就是说b的三个列表元素项都是引用的一个原先的列表元素项,
#实际上并没有新的列表元素项产生,这与直接定义b=[[1],[1],[1]]
#是截然不同的,直接定义的b其各列表元素项的id值是不同的

以上的文字解释可能还不太清楚,我们这里以图片辅助说明:

image

如图为a*3所得到的b的内存中的示意图,其0、1、2下标项所指向的都是列表元素项[1],而该项的下标0对应的又指向内存中的数值1。

image

如图为直接定义的b=[[1],[1],[1]]。可见其0、1、2下标项分别指向三个不同的列表元素项[1],而这三个不同的列表元素项的下标0对应的自然也都是内存中的数值1。

同时含有可变对象与不可变对象作为元素

a=[[1],2]
b=a*3
#则b为
[[1],2,[1],2,[1],2]
#并且仍然有
id(b[0])==id(b[2])==id(b[4])

总结

python中的这个现象,我个人认为更是一种语言实现上的bug,并不真的是什么有趣的知识点。很自然的逻辑,我们对于a*3得到的b,希望分别对b[0]和b[1]修改时,会发现竟然会是同时修改的(a=[[1]]),这太容易导致错误了,与一般性的逻辑不符。


鼠与我
7 声望1 粉丝

Sad