[Tutor] Python oddity

Luke Paireepinart rabidpoobear at gmail.com
Thu Feb 28 11:49:11 CET 2008


Brett Wilkins wrote:
> As everybody else has told you, assigning bb = aa just gives bb the 
> reference to the same object that aa has. Unless I missed something, 
> then nobody's actually mentioned how to make this not happen... and it's 
> actually rather easy... instead of bb = aa, do this:
> bb = aa[:]
> Looks like a splice, and indeed it is a splice, without bounds. When a 
> splice is used like this, I believe it is known as the copy directive.
Yes, Terry explained other ways as well.
The problem with using slices is the following:

 >>> a = [['a'],'b']
 >>> b = a
 >>> b is a
True
 >>> b = a[:]
 >>> b is a
False
#okay, we're fine so far.
 >>> b[0]
['a']
 >>> b[0].append('c')
 >>> b[0]
['a', 'c']
 >>> a[0]
['a', 'c']


and here's where we run into problems.
Turns out the slice notation just makes a shallow copy, so if you have 
any lists in your list, they will still refer to the same object.  (I'm 
guessing that any mutable objects will still refer to the same object)
copy.copy() has this same problem.
The way to avoid this, as I mentioned before, is to use a deepcopy(), 
but as I said, you usually don't need to make a full copy of a list.
Oh, and if you're curious:
 >>> b = list(a)
 >>> b is a
False
 >>> b[0].append('d')
 >>> a[0]
['a', 'c', 'd']

So a list() does a shallow copy as well.

Here's a continuation, with deepcopy():
 >>> import copy
 >>> b = copy.deepcopy(a)
 >>> b is a
False
 >>> b[0] is a[0]
False
 >>> b[0].append('e')
 >>> a[0]
['a', 'c', 'd']


HTH,
-Luke


More information about the Tutor mailing list