Syntax: pointers versus value

John Hunter jdhunter at ace.bsd.uchicago.edu
Wed Jul 30 23:10:30 CEST 2003


>>>>> "Danny" == Danny Castonguay <castong at mathstat.concordia.ca> writes:

    Danny> I want to avoid listA's value to change. 

There are several ways

  listB = listA[:]

  listB = [x for x in listA]

  import copy
  listB = copy.copy(listA)
  listB = copy.deepcopy(listA)

These don't all do the same thing, but all satisfy the example you
posted, eg

    >>> listA = [1 ,2]
    >>> listB = listA[:]
    >>> listB.append(3)
    >>> listA
    [1, 2]

So far so good, but consider this case

    >>> listA = [[],1]
    >>> listB = listA[:]
    >>> listB[0].append(12)  # changing the list at listB[0]
    >>> listB
    [[12], 1]
    >>> listA
    [[12], 1]

Sneaky, eh?  So the 'listB = listA[:]' made a copy of the list, but
not of the elements of the list.  This is a shallow copy, and you
should get the same behavior from copy.copy.  

Note that this is related to mutable and immutable objects in python.
In the example above, I didn't replace the first item of the list, I
changed it.  Since both listA and listB contained the same object as
their first element, changing one changes the other.  If I had
replaced that object in listB, nothing would have happened to listA

    >>> listA = [[],1]
    >>> listB = listA[:]
    >>> listB[0] = 12   # replacing the object, not changing it
    >>> listB
    [12, 1]
    >>> listA
    [[], 1]


If you want to avoid this, use deepcopy.

    >>> import copy
    >>> listA = [[],1]
    >>> listB = copy.deepcopy(listA)
    >>> listB[0].append(12)
    >>> listB
    [[12], 1]
    >>> listA
    [[], 1]

The behavior of mutable objects bites everyone a few times when they
begin learning python, so welcome to the club!

John Hunter





More information about the Python-list mailing list