Reputation: 3772
Why does multiple assignment make distinct references for ints, but not lists or other objects?
>>> a = b = 1
>>> a += 1
>>> a is b
>>> False
>>> a = b = [1]
>>> a.append(1)
>>> a is b
>>> True
Upvotes: 3
Views: 2204
Reputation: 8335
Python works differently when changing values of mutable object and immutable object
Immutable objects:
This are objects whose values which dose not after initialization
i.e.)int,string,tuple
Mutable Objects
This are objects whose values which can be after initialization
i.e.)All other objects are mutable like dist,list and user defined object
When changing the value of mutable object it dose not create a new memory space and transfer there it just changes the memory space where it was created
But it is exactly the opposite for immutable objects that is it creates a new space and transfer itself there
i.e.)
s="awe"
s[0]="e"
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-19-9f16ce5bbc72> in <module>()
----> 1 s[0]="e"
TypeError: 'str' object does not support item assignment
This is trying to tell u that you can change the value of the string memory you could do this
"e"+s[1:]
Out[20]: 'ewe'
This creates a new memory space and allocates the string there .
Like wise making A=B=1
and changing A A=2
will create a new memory space and variable A will reference to that location so that's why B's value is not changed when changing value of A
But this not the case in List since it is a mutable object changing the value does not transfer it to a new memory location it just expands the used memory
i.e.)
a=b=[]
a.append(1)
print a
[1]
print b
[1]
Both gives the same value since it is referencing the same memory space so both are equal
Upvotes: 2
Reputation: 39297
primitive types are immutable. When a += 1
runs, a
no longer refers to the memory location as b
:
https://docs.python.org/2/library/functions.html#id
CPython implementation detail: This is the address of the object in memory.
In [1]: a = b = 100000000000000000000000000000
print id(a), id(b)
print a is b
Out [1]: 4400387016 4400387016
True
In [2]: a += 1
print id(a), id(b)
print a is b
Out [2]: 4395695296 4400387016
False
Upvotes: 3
Reputation: 251578
The difference is not in the multiple assignment, but in what you subsequently do with the objects. With the int, you do +=
, and with the list you do .append
.
However, even if you do +=
for both, you won't necessarily see the same result, because what +=
does depends on what type you use it on.
So that is the basic answer: operations like +=
may work differently on different types. Whether +=
returns a new object or modifies the existing object is behavior that is defined by that object. To know what the behavior is, you need to know what kind of object it is and what behavior it defines (i.e., the documentation). All the more, you cannot assume that using an operation like +=
will have the same result as using a method like .append
. What a method like .append
does is defined by the object you call it on.
Upvotes: 1
Reputation: 64368
In the int example, you first assign the same object to both a
and b
, but then reassign a
with another object (the result of a+1
). a
now refers to a different object.
In the list example, you assign the same object to both a
and b
, but then you don't do anything to change that. append
only changes the interal state of the list object, not its identity. Thus they remain the same.
If you replace a.append(1)
with a = a + [1]
, you end up with different object, because, again, you assign a new object (the result of a+[1]
) to a
.
Note that a+=[1]
will behave differently, but that's a whole other question.
Upvotes: 7