2013-07-31 143 views
0

变量引用和赋值

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 

为什么?

回答

6

ab参考c,他们三个人都引用一个对象10

这意味着,执行c = 123不会改变物体背后c,它只会在一个新的对象123c,留下ab孤单。

换句话说,你原来:

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} 
+0

你的答案是如此之好...我只希望问题标题更具描述性,以便更多的人更有可能找到这个答案。 – SethMMorton

+0

非常感谢。 – Alcott