shengy
shengy

Reputation: 9749

Confused about assinging list items to vars in python

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

Answers (4)

Andrew Gorcester
Andrew Gorcester

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

sureshvv
sureshvv

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

Ashwini Chaudhary
Ashwini Chaudhary

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

alecxe
alecxe

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

Related Questions