Confusion: assignments create object references.

Peter Hansen peter at engcorp.com
Fri Apr 11 13:58:25 EDT 2003


"Havens, Peter" wrote:
> 
> I'm a silly rabbit. I hand copied the test incorrectly. The real test was:
> 
> >>> L = 1
> >>> M = L
> >>> L
> 1
> >>> M = 0
> >>> L
> 1
> >>>
> 
> Those are the real results (I double checked), but now I'm really confused. 
> Why does the former test (the one I lied about) above give expected results, 
> and the later doesn't?

Try this on for size:

The thing on the left side of the equal sign is "bound" (made to reference) 
the objects on the right side of the equal sign.  This is a universal, 
whether you are referring to simple names such as M and L, or *entries in
a list*, such as when you use M[0] and L[0].
 
The behaviour you show above is simple to explain, of course, as there is
never any relationship between M and L in this case.  Initially you
set L to be bound to the integer object containing the value 1.  Then
you copy the *reference* for that object to M, or to put it better, you
rebind the name M to the same object to which L is bound.

Later on, you rebind M to the different integer object containing the 
value 0.  L is of course not affected by this, so it stays bound to
the object 1.

Now take the case of lists.  The fundamental fact you are overlooking or
missing is that lists are *lists of references to things*.  Now you have
a list L, bound to a list object which contains three references, to the
objects 0, 1, and 2:

L = [0, 1, 2]

You bind the name M to the same object as L references: the *list* itself
(i.e. this has nothing to do with the objects referenced by the list).
So M and L "point" to the same object.

M = L

Now you go into that object, the list itself, via one of the *two* names
which are bound to it, and you index into it to find the first reference,
which is currently "pointing" to the integer object 0.  You then change
*that* reference to point to the integer object 9.  You have not changed
anything else in the list, and you have not in any way affected the names
which are bound to the *list*, only one of the references in the list.

M[0] = 9

When you then try to look at the list using the *other name* which is 
bound to it, you of course will get exactly the same list as you saw
using the other name:

>>> L[0]
9

In Python, think always in terms of objects and references to them, 
stored in names or as items in, for example, the list above.  If you
know about pointers, you won't be far off if you think of every name,
or every element in containers such as lists and tuples, as being
a pointer to some object.

(A lengthy explanation for what others have explained better and more
succinctly in the past.  Search the archives for them, and check the 
FAQ, if you are still confused.)

-Peter




More information about the Python-list mailing list