15

Can someone explain why the example with integers results in different values for x and y and the example with the list results in x and y being the same object?

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

4 Answers 4

8

Because integers are immutable, while list are mutable. You can see from the syntax. In x = x + 1 you are actually assigning a new value to x (it is alone on the LHS). In x[0] = 4, you're calling the index operator on the list and giving it a parameter - it's actually equivalent to x.__setitem__(0, 4), which is obviously changing the original object, not creating a new one.

Sign up to request clarification or add additional context in comments.

5 Comments

Is it not possible to get references to immutable objects?
All "variables" are references. Th difference is that you cannot change immutable objects. Once they are created, they never change - any attempted change will create a new object.
Stating "assigning a new value to x" is disingenuous and potentially confusing. What is happening is that a reference to a new object (result of x + 1) is bound to the name x. Python does not have the concept of lvalue/rvalue as everything is referenced - so the distinction is important.
@Jeremy Brown: I stand by my wording. The new value is the object created from evaluating the expression x + 1. After the assignment (that's what it is called in the Python documentation) x refers to the new value. And there's a concept of rvalue/lvalue in Python. It's not the same as in other languages, but it is there - that's why the left side of the = has to be a (usually singular) sequence of identifiers, not an expression, in the basic assignment statement. See: docs.python.org/reference/…
Note the wording of the first sentence (emphasis mine) - "Assignment statements are used to (re)bind names to values..." rvalue/lvalue has very specific meaning for C-like languages (this is not a general BNF concept). Your wording implies that there is a memory "slot" to which a value is assigned. That's not the case in Python and that's why you can't overload the assignment operator. I merely suggest using terms such as bind/rebind to completely disambiguate how assignment works. The most common pitfall I see with new Python programmers is not understanding that reference concept.
4

If you do y = x, y and x are the reference to the same object. But integers are immutable and when you do x + 1, the new integer is created:

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

When you have a mutable object (e.g. list, classes defined by yourself), x is changed whenever y is changed, because they point to a single object.

Comments

0

That's because when you have a list or a tuple in python you create a reference to an object. When you say that y = x you reference to the same object with y as x does. So when you edit the object of x y changes with it.

2 Comments

“when you have a list or a tuple” is pretty misleading.
Yeah I'm sorry about that. What I meant to say was that it doesn't matter which of the two, since they are both immutable.
0

As the previous answers said the code you wrote assigns the same object to different names such aliases. If you want to assign a copy of the original list to the new variable (object actually) use this solution:

>>> 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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.