Why does changing 1 list affect the other?

Francis Avila francisgavila at yahoo.com
Fri Nov 7 15:41:31 EST 2003


"Louis Pecora" <pecora at anvil.nrl.navy.mil> wrote in message
news:pecora-9C8FEE.14325507112003 at ra.nrl.navy.mil...
> So the action is on the binding end?  Only one 5 is created, but the x=4
> following statement UNbinds x and rebinds it to '4', rather than
> changing the object. y remains bound to '5'.  Did that come out right?
>
> Then for lists, when we do   x[0]=4 we are NOT unbinding x, but rather
> just changing the object?
>
> Sounds like if we try harder we will get to the _binding_ actions of the
> '=' operator.  Let me try harder right here (off the top of my head).
>
> So, let's see, we view '=' as a binding operation.
>
> x=list
>
> binds x to the list, but each list element is bound to something else (I
> refer to this as a second level binding).
>
> For lists we are allowed to change that second level binding.  This
> second level action does NOT affect the first level y=x binding.
>
> Now, does that sound right?  Anyone?
>
> -- Lou Pecora

This "first order, second order" binding is just confusing things, I think.

Try this:

There are two kinds of "things" in Python--names and objects.

1) Names point to objects, and only to objects
2) Names are not objects.

It follows from this that names never point to names, AND that objects can
CONTAIN names.  So, names are THINGS, but not OBJECTS.  Names are like
arrows that you can hold and point at things with, but that can't be pointed
to.

If you say something like "y = x", you're saying, "whatever object x points
to, make y point to the *same* object." (NOT a *copy* of that object!)

Further, some names are explicit, some implicit (or "anonymous," if you
don't mind the slight contradiction that entails....).  Container objects
(dictionaries, lists, tuples) contain "anonymous names" which point to
objects.  These implicit names are accessed indirectly only by an index or
key, not directly by a name in a namespace.

If the container is "mutable", then the implicit names contained within the
container object can be made to point to different objects after the
container object's creation.

This is the behavior we see in a list:

>>> firstlist=['item1','item2','item2']
Make a list-type container object with three implicit names.  Make those
implicit names point to three different string objects.
Then make the name firstlist point to that just-created list object.
>>> secondlist=firstlist
Make a name secondlist which points to the same list firstlist points to.
>>> print (firstlist,secondlist)
(['item1', 'item2', 'item2'], ['item1', 'item2', 'item2'])
Create a tuple-type container object, with two implicit names, which point
to the objects pointed to by firstlist and secondlist (which end up being
the same identical object.)
Note that this tuple is never bound to a name, so it will be garbage
collected eventually.
>>> firstlist[0]='strangeness'
Make the zeroth implicit name (which is contained in the object pointed to
by "firstlist") point at the new string object 'strangeness'.
>>> print (firstlist,secondlist)
(['strangeness', 'item2', 'item2'], ['strangeness', 'item2', 'item2'])
firstlist and secondlist *still* point to the same object.  It's just that
the object was changed.

--
Francis Avila






More information about the Python-list mailing list