List Problem

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Sep 23 18:07:22 EDT 2012


On Sun, 23 Sep 2012 14:31:48 -0700, jimbo1qaz wrote:

> I have a nested list. Whenever I make a copy of the list, changes in one
> affect the other, 

Then you aren't making a copy.

py> first_list = [1, 2, 3]
py> second_list = first_list  # THIS IS NOT A COPY
py> second_list.append(9999)
py> print first_list
[1, 2, 3, 9999]


> even when I use list(orig) 

Nonsense. Either you are confused, or there is something you aren't 
telling us. Calling list *does* make a copy:

py> first_list = [1, 2, 3]
py> second_list = list(first_list)
py> second_list.append(9999)
py> print first_list
[1, 2, 3]

What aren't you telling us? My guess is that there are TWO lists 
involved, and you're only copying ONE:


py> a = [1, 2, 3]
py> a.append(["ham", "spam", "cheese"])
py> print a
[1, 2, 3, ['ham', 'spam', 'cheese']]
py> b = list(a)  # make a copy of a, but not the contents of a
py> b.append(99)  # change b
py> b[-1].append("tomato")
py> print a
[1, 2, 3, ['ham', 'spam', 'cheese', 'tomato']]

Notice that b is a copy of a: changing b does not change a. But the 
embedded list within a is *not* copied, so whether you append to that 
list via a or b is irrelevant, both see the same change because there is 
only one inner list in two places.

It might be more obvious if you give the shared sublist a name:

c = ['ham', 'spam', 'tomato']
a = [1, 2, 3, c]
b = [1, 2, 3, c]  # a copy of a, but not a copy of c

Now it should be obvious that any changes to c will show up in both a and 
b, regardless of how you change it. All three of these will have the 
exact same effect:

a[-1].append('eggs')
b[-1].append('eggs')
c.append('eggs')


The way to copy lists, and all their sublists, and their sublists, and so 
on all the way down, is with the copy module:

import copy
b = copy.deepcopy(a)

but if you are doing this a lot, (1) your code will be slow, and (2) you 
can probably redesign your code to avoid so many copies.

By the way, instead of dumping lots of irrelevant code on us, please take 
the time to narrow your problem down to the smallest possible piece of 
code. We're volunteers here, and you are not paying us to wade through 
your code trying to determine where your problem lies. That is up to you: 
you narrow down to the actual problem, then ask for help.

Please read http://sscce.org/ for more details of how, and why, you 
should do this.


Thank you.



-- 
Steven



More information about the Python-list mailing list