[Tutor] (no subject)
Daniel Yoo
dyoo@hkn.EECS.Berkeley.EDU
Fri, 1 Sep 2000 01:39:20 -0700 (PDT)
On Fri, 1 Sep 2000, deng wei wrote:
> Hello All:
> If I want to duplicate a list,how should I do?
> I had tried,for example:
>
> a=['Hello','world']
> b=a
>
> but obviously it's not right.
>
> Anyone knows? Thanks!
The quick answer is:
b = a[:]
which will make a shallow copy of the list. What this does is take a
slice of all of 'a'. A better answer would be to use the 'copy' module,
which will make "deep" copies:
###
import copy
b = copy.deepcopy(a)
###
which guarantees that b has a completely separate copy of whatever 'a'
contained.
Here's a slightly more detailed explanation of what's happening: For the
immutable types (strings, tuples, numbers), you usually don't have to
worry about copying stuff.
###
>>> a = 42
>>> b = a
>>> b = 24
>>> a,b
(42, 24)
###
does what you expect. Since these things don't change, it's fine when
they share the same thing. This is, in fact, what's happening --- it's
sharing. Here's a diagram of what it looks like in your computer after
'b = a':
|-|
|a|----------|
|-| | |--|
|----> |42|
|-| | |--|
|b| ---------|
|-|
However, since lists are "mutable", that is, modifiable, this rule causes
difficulties, as you noticed, if you're making changes to the shared
thing.
>>> a = ['hello', 'world']
>>> b = a
>>> a[0] = 'goodbye'
>>> a
['goodbye', 'world']
>>> b
['goodbye', 'world']
Diagrammically, this looks like:
|-|
|a|----------|
|-| | |----------------------|
|----->| ['goodbye', 'world'] |
|-| | |----------------------|
|b| ---------|
|-|
As explained above, the way to fix this is to give 'b' an independent copy
of the list:
>>> a = ['hello', 'world']
>>> import copy
>>> b = copy.deepcopy(a)
>>> a[0] = 'goodbye'
>>> a
['goodbye', 'world']
>>> b
['hello', 'world']
By using the [:] slice, or the copy.deepcopy() function, we'll get this
picture instead:
|-| |----------------------|
|a|--------->| ['goodbye', 'world'] |
|-| |----------------------|
|-| |--------------------|
|b|--------->| ['hello', 'world'] |
|-| |--------------------|
which does the thing you expect for your particular program. Usually,
sharing is fine, but there are cases when you want to explicitly copy
stuff.
I hope this makes things clearer, even if the ASCII is a bit ugly...
*grin*