Ocasionally, it is useful to copy a list that we already have created in order to initialize a new list that is going to be used for another purpose.  We need the original list to remain intact with modifications taking place in the new list.  How to copy a list and preserve the original?

     It may seem easy, but if we use this first method shown below, we are going to get ourselves in trouble fast, because it doesn’t copy the list.  It only creates a new list variable pointing to the same place in memory.  

# Method 1 is incorrect for copying lists!
list1 = [“one”, “two”, “three”]
list2 = list1
list2.append(“four”)
print(“list1 has:”, list1)
print(“list2 has:”, list2)

Output from Method 1:

list1 has: [‘one’, ‘two’, ‘three’, ‘four’]
list2 has: [‘one’, ‘two’, ‘three’, ‘four’]

As you can see, four was added to both lists.  This is not what we want!  

     We can actually use slicing to create a copy of a list.  Simply slice from the beginning of a list to the end and save that to a new variable.  Now you have a copy of a list.

# Method 2 uses slicing and works great for copying a list.
list1 = [“one”, “two”, “three”]
list2 = list1[:]
list2.append(“four”)
print(“list1 has:”, list1)
print(“list2 has:”, list2)

Output from Method 2:

list1 has: [‘one’, ‘two’, ‘three’]
list2 has: [‘one’, ‘two’, ‘three’, ‘four’]

This time, four was only added to the new list.  The old list is preserved, exactly what we want. 

     There is another method to use, which accomplishes the same thing, and that is to use the list function.  Below is how it works.

# Method 3 uses the list function to help accomplish our goal 
list1 = [“one”, “two”, “three”]
list2 = list(list1)
list2.append(“four”)
print(“list1 has:”, list1)
print(“list2 has:”, list2)

Output from Method 3:

list1 has: [‘one’, ‘two’, ‘three’]
list2 has: [‘one’, ‘two’, ‘three’, ‘four’]

As you can see, this worked fine as well.

     However, what happens if we have a nested list.  How do we copy that?

# Previous working methods do NOT work for copying a nested list!
list1 = [[“one”, “two”, “three”], [“a”, “b”, “c”]]
list2 = list1[:]
list2.append([“A”, “B”, “C”])
print(“list1 has:”, list1)
print(“list2 has:”, list2)

Output from the first part of the code:

list1 has: [[‘one’, ‘two’, ‘three’], [‘a’, ‘b’, ‘c’]]
list2 has: [[‘one’, ‘two’, ‘three’], [‘a’, ‘b’, ‘c’], [‘A’, ‘B’, ‘C’]]

     This appears to have worked, but it only works if modifying the outer list.  Continue reading to see what happens when we try to modify an inner list.

# Continuation of code above
list2[0].append(“four”)
print(“list1 has:”, list1)
print(“list2 has:”, list2)

Output from modifying an inner list:

list1 has: [[‘one’, ‘two’, ‘three’, ‘four’], [‘a’, ‘b’, ‘c’]]
list2 has: [[‘one’, ‘two’, ‘three’, ‘four’], [‘a’, ‘b’, ‘c’], [‘A’, ‘B’, ‘C’]]

Notice that four was added to the first inner list of list1 and list2.  This is not what we want.

     In order to copy a nested list and preserve the original, we must import the deepcopy function from Python’s copy module and use it.

# Using the deepcopy function from the copy module allows us to safely copy a nested list
from copy import deepcopy
list1 = [[“one”, “two”, “three”], [“a”, “b”, “c”]]
list2 = deepcopy(list1)
list2[0].append(“four”)
print(“list1 has:”, list1)
print(“list2 has:”, list2)

Output from the deepcopy code:

list1 has: [[‘one’, ‘two’, ‘three’], [‘a’, ‘b’, ‘c’]]
list2 has: [[‘one’, ‘two’, ‘three’, ‘four’], [‘a’, ‘b’, ‘c’]]

As you can see, this time, four was only added to our copy.  The original list is preserved.

Leave a Reply

Your email address will not be published. Required fields are marked *