[Tutor] 'in-place' methods

w chun wescpy at gmail.com
Sat Feb 18 19:06:00 CET 2006


> Perhaps you've seen this already, but since you are wrapping the print
> in a function, I suspect you want the original list to be unmodified.
> Thus, compare:
>
>  >>> def sort_print1(a_list):
>         a_list.sort()
>         print a_list
>
>
>  >>> def sort_print2(a_list):
>         t = list(a_list)
>         t.sort()
>         print t
>
>  >>> list1 = ["sort_print1", "mutates", "the", "original"]
>  >>> list2 = ["sort_print2", "doesn't", "mutate", "the", "original"]
>  >>> sort_print1(list1)
> ['mutates', 'original', 'sort_print1', 'the']
>  >>> list1
> ['mutates', 'original', 'sort_print1', 'the']
>  >>> sort_print2(list2)
> ["doesn't", 'mutate', 'original', 'sort_print2', 'the']
>  >>> list2
> ['sort_print2', "doesn't", 'mutate', 'the', 'original']


this is a slight tangent to mike's original question but is *another*
gotcha for newbies who are swimming in the new waters of Python
objects.  and that is, that although Brian appears to make a copy of
the original list in sort_print2() using the list() factory built-in
function, it is only (called) a "shallow copy."

bear in mind that if you use list() to generate a(nother) list object,
you are only copying references or aliases to the objects in the
original data structure (here it is also a list), whether mutable or
otherwise; but if it is the former, then be aware that you are NOT
MAKING A COPY of those mutable objects, just references.  those
objects can then be modified whether you access the original or the
one in the shallow copy:

>>> def sort_print2(a_list):
    t = list(a_list)
    t[-1][-1] = 'Yes'
    t.sort()
    print t

>>> foo = [ 'Have I been trumped?', 'No' ]
>>> myList = [ 456, 'abc', 1.23, foo ]
>>> sort_print2(myList)
[1.23, 456, ['Have I been trumped?', 'Yes'], 'abc']
>>> myList
[456, 'abc', 1.23, ['Have I been trumped?', 'Yes']]
>>>

see how i'm modifying 't' and not 'a_list'.  changing either one will
have the exact same outcome because they both contain a reference to
the same object 'foo'.  in other words, no copy of 'foo' was made, so
that's why it's affected.

if you really need a complete copy (of objects *and* the ones
contained within recursively), then read up on the deepcopy() function
of the copy module. (caveat tho, that is doesn't copy EVERYTHING, but
enough to make you feel like it does.  for example, it doesn't copy
files, functions/methods, stack frames, etc.)

cheers,
-wesley
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Core Python Programming", Prentice Hall, (c)2006,2001
    http://corepython.com

wesley.j.chun :: wescpy-at-gmail.com
cyberweb.consulting : silicon valley, ca
http://cyberwebconsulting.com


More information about the Tutor mailing list