说
c = 10
a = b = c
现在a,b
引用c
,所以我想如果c
发生变化,那么a,b
也会发生变化,例如
c = 123 # change c, then a = b = 123
但实际上,a,b
根本没有变化,为什么?现在考虑一个列表
m = [0]
l = [m]*3
l[0][0] = 1 # just change l[0][0], then l[1:] change
为什么?
答案 0 :(得分:6)
a
和b
不引用c
,所有这三个引用对象10
。
这意味着执行c = 123
不会更改 c
后面的对象,只会将c
指向新对象123
,单独留下a
和b
。
换句话说,你原来是:
a ---+
|
b ---+---> 10-object
|
c ---+
并执行c = 123
将其更改为:
a ---+
|
b ---+---> 10-object
c -------> 123-object
你越早意识到Python真的 完全面向对象,你就会越快地理解语言: - )
您的第二个示例更改l
中所有元素的原因是l
列表中的所有项都引用了单个list1
而不是不同支持对象:
l -------> list2 {list1, list1, list1}
m -------> list1 {0-object}
执行l[0][0] = 1
与执行m[0] = 1
(见下文)相同,不会将m
的绑定更改为其列表,或绑定list2
到list1
中的这些项目,而只是将 list2
中的项更改为1-object
:
l -------> list2 {list1, list1, list1}
m -------> list1 {1-object}
因此,您可以看到对list1
内容的更改会影响所有内容。显示l[0][0]
和m[0]
等效的成绩单如下所示:
>>> m = [0]
>>> l = [m] * 3
>>> m
[0]
>>> l
[[0], [0], [0]]
>>> l[0][0] = 1
>>> l
[[1], [1], [1]]
>>> m
[1]
>>> m[0] = 42
>>> l
[[42], [42], [42]]
请注意,如果更改m
的绑定,则不会更改list2
中的实际绑定:
>>> m = [999]
>>> l
[[42], [42], [42]]
当你这样做时,你最终得到:
l -------> list2 {list1, list1, list1}
list1 {42-object}
m -------> list3 {999-object}