1

I have a problem when I try to work with a list and a copy of it. I know that there are certain ways to copy a list in Python and I think that I follow them. Here is my problem.

a = []
for i in range(10):
    a.append([0]*10)

b = a[:]

for j in a:
    j[0] = 1

print a
print b

I create a blank list. Then I add 10 sublists of zeros ([0,0,0,0,0....]). Then I copy the list and finally I iterate through the first one. But when I print them, both lists have been changed.

Sfinos
  • 279
  • 4
  • 15

4 Answers4

7

You only created a shallow copy. This creates a new list with references to the contained values. The lists contained in a are still being shared between the lists a and b.

You can add a level of copying:

b = [elem[:] for elem in a]

This creates a new list object, containing shallow copies of the nested lists from a. Since the nested lists themselves contain immutable objects only (integers) this is enough here.

Or you can use copy.deepcopy() to have a library function do this for you, creating a copy by recursing over your structure and creating copies of anything mutable.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2

To make a proper copy use copy module

b = copy.deepcopy(a)
Alex Shkop
  • 1,992
  • 12
  • 12
2

Another way of creating a deep copy is to use the copy.deepcopy function of the copy module: doc

timgeb
  • 76,762
  • 20
  • 123
  • 145
2

3 options:

  • Use the built in list() function combined with a generator

b = list(list(item) for item in a)

  • List comprehension

b = [item[:] for item in a]

import copy b = copy.deepcopy(a)

Chris Clarke
  • 2,103
  • 2
  • 14
  • 19
  • b = [item for item in a] doesn't seem to work while b = [item[:] for item in a]--as suggested in the answer below--does (with python 2.7) – user2314737 Jun 02 '14 at 14:49
  • ah, sorry, yes, really must read the question properly, need to copy the lists within the lists, rather than just copy the list, updated – Chris Clarke Jun 02 '14 at 14:51