Reputation: 9749
Say I have a list:
L = [1,2,3]
and I assigned L[0]
to a variable a
a = L[0]
then if I change a
, it won't affect L
.
a = a + 1
print L # [1,2,3] not affected
Why is this happening? isn't python passing everything around with references? I thought that a
is pointing to L[0]
Upvotes: 1
Views: 103
Reputation: 19963
L[0]
is a name, and when you create the list L
, you assign an object to that name, the integer 1. a
is also a name, and when you assign a as in a = L[0]
, you make a
to point to the same object that L[0]
points to.
But when you later do a = a + 1
, this is another assignment. You are not modifying the object that a
points to -- the =
sign can't do that. You are creating a new object, the integer 2, and assigning that to a
.
So in the end, you have two objects in memory; one is referred to by L[0]
and the other is referred to by a
.
Integers are immutable, which means that there is no possible way to change the properties of the objects in this example; however, that's not salient in this example exactly, because even if the object was mutable it wouldn't change the fact that you're doing assignment (with the =
sign). In a case where the object in question was mutable, you could theoretically change the properties of the object when it is still referenced by L[0]
and a
, instead of doing any additional assignment with =
as you are doing. At that point, you would see the properties change regardless of which name you used to inspect the object.
Upvotes: 2
Reputation: 4412
Change the assignment to:
a = L
then when you change L as:
L[0] += 1
you will see that a also changes. This is the reference magic.
Upvotes: 0
Reputation: 250891
The problem is that a
and L[0]
are references to an immutable object, so changing any one of them won't affect the other references:
>>> L = [1, 2, [3]]
>>> a = L[0]
>>> a = a + 1
a
now points to a new object, while L[0]
still points to the same object.
>>> a, L[0]
(2, 1)
Now in this case b
and L[2]
are references to a mutable object(list
), any in-place operation on them will affect all the references:
>>> b = L[2]
>>> b.append(4) #list.append is an in-place operation
>>> b, L[2]
([3, 4], [3, 4])
>>> b = b + [5] #mutable object, but not an in-place operation
>>> b #b is assigned to new list object
[3, 4, 5]
>>> L[2] #L[2] is unchanged
[3, 4]
Upvotes: 3
Reputation: 473813
Since L[0]
in your case is immutable, changing a
doesn't affect the value of L[0]
. When you change a
, the new object is created and a
starts to pointing to it.
See what happens if L[0]
is of a mutable type:
>>> L = [[1],2,3]
>>> a = L[0]
>>> a.append(2)
>>> L
[[1, 2], 2, 3]
In this case a
and L[0]
both point to the same object.
Also see Raymond Hettinger's answer in the relevant thread.
Upvotes: 1