Python references
有人能解释为什么带整数的例子会导致x和y的值不同,而带列表的例子会导致x和y是同一个对象吗?
1 2 3 4 5 6 7 8 9 10 11 12
| 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 |
- y=list(x)。
- 过多的时间
- 哇!这看起来就像是一个什么样的我在问问题2573135 stackoverflow.com / / / 2573965 # 2573965
我读过的最好的解释是:http://python.net/~goodger/projects/pycon/2007/惯用/讲义.html其他语言有变量
因为整数是不可变的,而列表是可变的。从语法中可以看到。在x = x + 1中,您实际上为x分配了一个新值(仅在lhs上)。在x[0] = 4中,您调用列表上的index操作符并给它一个参数—它实际上相当于x.__setitem__(0, 4),这显然改变了原始对象,而不是创建新对象。
- 是否不可能获取对不可变对象的引用?
- 所有"变量"都是引用。区别在于你不能改变不变的对象。一旦创建了它们,它们就不会更改-任何尝试的更改都将创建一个新对象。
- 声明"将新值赋给X"是不真实的,并且可能令人困惑。正在发生的是,对新对象的引用(x+1的结果)绑定到了名称x上。由于引用了所有内容,所以python没有lvalue/rvalue的概念,因此区分非常重要。
- @杰里米·布朗:我坚持我的措辞。新值是通过计算表达式x + 1创建的对象。在赋值之后(在Python文档中就是这样称呼的),x引用了新的值。在python中有一个rvalue/lvalue的概念。它与其他语言不同,但确实存在——这就是为什么=的左侧必须是基本赋值语句中的标识符(通常是单数)序列,而不是表达式。参见:docs.python.org/reference/…
- 注意第一句(emphasis mine)-"赋值语句用于(重新)将名称绑定到值…"rvalue/lvalue对于类似C语言有非常具体的含义(这不是一般的bnf概念)。您的措词意味着有一个内存"槽",将一个值分配给它。这不是Python中的情况,这就是为什么不能重载赋值操作符的原因。我只建议使用绑定/重新绑定等术语来完全消除分配的工作方式。对于新的Python程序员,我看到的最常见的陷阱是不理解这个引用概念。
如果执行y = x,则y和x是对同一对象的引用。但是整数是不可变的,当您执行x + 1操作时,将创建新的整数:
1 2 3 4 5 6 7 8 9
| >>> x = 1
>>> id(x)
135720760
>>> x += 1
>>> id(x)
135720748
>>> x -= 1
>>> id(x)
135720760 |
当你有一个可变的对象(例如列表,你自己定义的类)时,每当y改变时,x就会改变,因为它们指向一个单一的对象。
正如前面的答案所说,您编写的代码将相同的对象分配给不同的名称,例如别名。如果要将原始列表的副本分配给新变量(实际上是对象)使用此解决方案:
1 2 3 4 5 6 7 8 9 10 11
| >>> 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] |
这是因为当您在Python中有一个列表或元组时,您将创建一个对对象的引用。当你说y=x时,你引用的是与x相同的带有y的对象。所以当你编辑x y的对象时,它会随之改变。
- 比公认的答案更不迷惑。
- "当你有一个列表或一个元组"是相当误导。
- 是的,我很抱歉。我想说的是,这两者中的哪一个无关紧要,因为它们都是不可变的。