Making a Copy of a List in Python

In Python, assignment works by reference. For example, when you try to copy a list like this: list = another_list, you encounter a peculiar (but actually intended) behavior:

a = ["a","b","c"]
>>> b = a
>>> b.append("d")
>>> print a, b
['a', 'b', 'c', 'd'] ['a', 'b', 'c', 'd']

This behavior applies to objects as well. When you assign an object like this: object = another_object, you're creating a reference to the original object:

>>> class obj:
...     def __init__(self):
...         self.counter = 0
...     def inc(self):
...         self.counter += 1
... 
>>> a = obj()
>>> b = a
>>> a.inc()
>>> print a.counter
1
>>> print b.counter
1

When you want to make a copy of a variable or object, there are several methods to achieve that. The most elegant method I’ve found for copying data structures (such as lists, tuples, dictionaries, etc.) is as follows:

>>> a = ["a","b","c"]
>>> b = list(a)
>>> print a , b
['a', 'b', 'c'] ['a', 'b', 'c']
>>> a.append("d")
>>> print a, b
['a', 'b', 'c', 'd'] ['a', 'b', 'c']

What if we want to copy an object? For that, there is a copy module:

>>> class obj:
...     def __init__(self):
...         self.counter = 0
...     def inc(self):
...         self.counter += 1
... 
>>> a = obj()
>>> from copy import copy
>>> b = copy(a)
>>> a.inc()
>>> b.inc()
>>> b.inc()
>>> b.inc()
>>> print a.counter, b.counter
1 3

If we import the deepcopy function from the copy module and use it, we can make a recursive copy of an object.

07/2011