473,583 Members | 3,460 Online

# Copy a list

39 New Member
Consider the following code:
Expand|Select|Wrap|Line Numbers
1. listA = [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']]
2. changeCoordinates = ((2, 3), (1, 3))
3.
4. for coordinateList in changeCoordinates:
5.     listB = listA[:]
6.     x = coordinateList[0]
7.     y = coordinateList[1]
8.
9.     listB[x][y] = 'foo'
10.     print "list A: %s" % listA
11.     print "list B: %s" % listB
12.
listA should never change. But it does. It works the way I expected on a one-dimensional list, but on a two-dimensional list, listA changes. How do I avoid this, and (out of curiosity) why the hell doesn't python just assign the value rather than the reference anyway?
Aug 21 '08 #1
3 2047
boxfish
469 Recognized Expert Contributor
Hi,
listB is actually a separate copy of listA, but each of the sub-lists in listB is just a shallow copy of the corresponding sub-list in listA, if that makes any sense. To make a completely independent copy of listA, you will either have to use a loop like this:
Expand|Select|Wrap|Line Numbers
1. for sub_list in listA:
2.     listB.append(sublist[:])
or use the deepcopy() function of the copy module:
Expand|Select|Wrap|Line Numbers
1. import copy
2. listB = copy.deepcopy(listA)
Hope this helps.
Aug 21 '08 #2
39 New Member
OK thanks. And about the second part of my question...is there any logical reason for python to do this? Isn't it inconsistent for the assignment operator to assign a value to some data types and a reference to others? Just wondering why they did this.
Aug 21 '08 #3
boxfish
469 Recognized Expert Contributor
Not sure. Seems like the only types that get copied as a reference are lists and object types. I think it would make more sense if tuples, strings, and dictionaries got copied as references too, because they can get really huge also. I wonder if there's a way to do shallow copying of those types in Python.
Aug 21 '08 #4