2010-05-09 59 views
15

有人可以解释为什么整数的例子为x和y产生不同的值,而列表的例子中x和y是相同的对象?Python的参考

x = 42 
y = x 
x = x + 1 
print x # 43 
print y # 42 

x = [ 1, 2, 3 ] 
y = x 
x[0] = 4 
print x # [4, 2, 3] 
print y # [4, 2, 3] 
x is y # True 
+1

'Y =列表(x)'* – 2010-05-09 09:07:58

+0

欺骗了许多倍 – SilentGhost 2010-05-09 09:08:25

+0

哇!这看起来就像我上个月在问起http://stackoverflow.com/questions/2573135/2573965#2573965 – wescpy 2010-05-10 04:30:36

回答

8

因为整数是不可变的,而列表是可变的。你可以从语法中看到。在x = x + 1中,您实际上正在为x分配一个新值(它仅在LHS中)。在x[0] = 4中,您正在调用列表中的索引运算符并给它一个参数 - 它实际上相当于x.__setitem__(0, 4),这显然会更改原始对象,而不是创建新对象。

+0

不可能获得对不可变对象的引用吗? – hekevintran 2010-05-09 10:06:56

+3

所有“变量”都是引用。差别在于你不能改变不可变的对象。一旦它们被创建,它们就不会改变 - 任何尝试的改变都会创建一个新的对象。 – 2010-05-09 10:11:09

+2

陈述“给x分配一个新值”是不真诚的,可能会令人困惑。发生的事情是对新对象的引用(x + 1的结果)绑定到名称x。 Python并没有左值/右值的概念,因为一切都被引用 - 所以区别很重要。 – 2010-05-09 13:02:52

0

这是因为当你在Python中有一个列表或元组时,你可以创建一个对象的引用。 当你说y = x时,你引用与y相同的对象。 所以,当你编辑x的对象随着它而改变。

+0

比接受的答案更容易混淆。 – 2013-03-12 21:41:37

+2

“当你有一个列表或一个元组”是相当具有误导性的。 – Ryan 2013-06-20 14:01:44

+0

对,我很抱歉。 我的意思是说,两者中的哪一个并不重要,因为它们都是不可变的。 – Bloeper 2013-07-19 08:29:15

4

如果你这样做y = x,Y和X是参照同一个对象。但整数是不变的,当你做x + 1,创建新的整数:

>>> x = 1 
>>> id(x) 
135720760 
>>> x += 1 
>>> id(x) 
135720748 
>>> x -= 1 
>>> id(x) 
135720760 

当你有一个可变对象(如列表,自己定义的类),每当y发生了改变x被改变,因为它们指向到一个单一的对象。

0

正如之前的答案所说,您写的代码将不同的名称(如别名)分配给同一个对象。 如果你想原始列表的副本分配给新的变量(对象实际上) 使用此解决方案:

>>> x=[1,2,3] 
>>> y=x[:] #this makes a new list 
>>> x 
[1, 2, 3] 
>>> y 
[1, 2, 3] 
>>> x[0]=4 
>>> x 
[4, 2, 3] 
>>> y 
[1, 2, 3]