obj2 = ojb1 = range(len(somelist))

David Bolen db3l at fitlinxx.com
Thu Jan 31 20:11:50 EST 2002


"Sean 'Shaleh' Perry" <shalehperry at attbi.com> writes:

> to summarize the other posts, when you copy a list you get a shallow
> copy (they all point to the same place).  The only way around this
> is to force a full copy of the list which ends up being about as
> good as just calling range again.

Well, I wouldn't call what you get with assignment a shallow copy -
it's no copy at all.  You just get a second reference to the
original object.  No new object creation is involved.

> list[:] works becuase it creates a new list

Yes, a new list, but only a shallow copy of the original list.  That
is, it gives you a new container object (the list itself), but does
not recurse into the original list and duplicate objects it contains.
So your new list is a new object, but it contains references to the
original set of objects.

> import copy
> copy.copy() implements a deep copy, which is basically the same as list[:].

Actually, copy.copy() is a shallow copy, and yes for sequences should
be the same as [:].

If you want a deep copy (recursion and duplication of all objects),
then you want to use copy.deepcopy().  When used on a list, you'll
get not only a new top level list object, but new copies of objects
contained within the list.  Although I believe that for immutable
objects, even in a deepcopy you'll have references to the original
object, since there's really no reason to have a separate instance.

As a sample:

    >>> original = [1,[2,3]]
    >>> id(original),id(original[0]),id(original[1])
    (8270464, 8080288, 8270432)

Assignment doesn't change anything at all, just gives us a new label
that is bound to the same object.

    >>> newassign = original
    >>> id(newassign),id(newassign[0]),id(newassign[1])
    (8270464, 8080288, 8270432)

Taking the full slice gives us a new list object, but its contents are
the same original objects, including the nested list.

    >>> newlist = original[:]
    >>> id(newlist),id(newlist[0]),id(newlist[1])
    (8281712, 8080288, 8270432)

And copy.copy() behaves the same as the full slice:

    >>> newcopy = copy.copy(original)
    >>> id(newcopy),id(newcopy[0]),id(newcopy[1])
    (8285456, 8080288, 8270432)

However, copy.deepcopy() also creates a new list for the contained
list object:

    >>> newdeep = copy.deepcopy(original)
    >>> id(newdeep),id(newdeep[0]),id(newdeep[1])
    (8286496, 8080288, 8286608)


--
-- David
-- 
/-----------------------------------------------------------------------\
 \               David Bolen            \   E-mail: db3l at fitlinxx.com  /
  |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
 /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
\-----------------------------------------------------------------------/



More information about the Python-list mailing list