In this post, we’ll try to understand the difference between shadow copy and deep copy in Python. We study the copy behavior with list data structure in Python.

## Problem statement

Assuming we have the following list:

``````test_list = [1, 2, [3, 6], 4, 5]
``````

We want to create a duplicate list so that we can modify the contents independently without affecting the original list.

``````test_list_clone = [1, 2, [3, 6], 4, 5]
test_list_clone[0] = 11
test_list_clone[2].append(11)
print(test_list)
print(test_list_clone)
``````

The expected output should be:

[1, 2, [3, 6], 4, 5]

[11, 2, [3, 6, 11], 4, 5]

How should we copy the original list?

## Duplicate reference

It’s not uncommon that you may want to copy the list as below.

``````test_list_clone = test_list
test_list_clone[0] = 11
test_list_clone[2].append(11)
print(test_list)
print(test_list_clone)
``````

Output:

[11, 2, [3, 6, 11], 4, 5]

[11, 2, [3, 6, 11], 4, 5]

This doesn’t work since it simply stores the list reference to another variable. When the duplciate list is modified, the original list is also modified.

## Copy list by brute force

In this solution, we append each item in the original list to the duplicate list by using a list comprehensions(a short form of for loop).

``````test_list_clone = [item for item in test_list]
test_list_clone[0] = 22
test_list_clone[2][-1] = 22
print(test_list)
print(test_list_clone)
``````

Output:

[11, 2, [3, 6, 22], 4, 5]

[22, 2, [3, 6, 22], 4, 5]

This works partially but not for the nested list. This is because it only duplicates the outer list. But the inner list is still duplicated as a reference of original object. That’s why the number 22 is appended to both the duplciate list and original list.

## Copy list with slice

We can get a subset of the list with slice in Python. The colon means to get the whole copy as original. Again, this only duplicates the outer list.

``````test_list_clone = test_list[:]
test_list_clone[0] = 33
test_list_clone[2][-1] = 33
print(test_list)
print(test_list_clone)
``````

Output:

[11, 2, [3, 6, 33], 4, 5]

[33, 2, [3, 6, 33], 4, 5]

## Copy list with list constructor

A more readable form might be using list constructor to duplciate the list. But it has the same issue without deep copy of inner list.

``````test_list_clone = list(test_list)
test_list_clone[0] = 44
test_list_clone[2][-1] = 44
print(test_list)
print(test_list_clone)
``````

Output:

[11, 2, [3, 6, 44], 4, 5]

[44, 2, [3, 6, 44], 4, 5]

## Copy list with starred expression

Another way is to use starred expression to duplciate the list.

``````test_list_clone = [*test_list]
test_list_clone[0] = 55
test_list_clone[2][-1] = 55
print(test_list)
print(test_list_clone)
``````

Output:

[11, 2, [3, 6, 55], 4, 5]

[55, 2, [3, 6, 55], 4, 5]

## Copy list with copy function, python 3.3+

In Python 3.3+, a copy function of the list is available. But it doesn’t do the deep copy either.

``````test_list_clone = test_list.copy()
test_list_clone[0] = 66
test_list_clone[2][-1] = 66
print(test_list)
print(test_list_clone)
``````

Output:

[11, 2, [3, 6, 66], 4, 5]

[66, 2, [3, 6, 66], 4, 5]

## Copy list with multiplication

A tricky way to duplciate the list is to use multiplication style.

``````test_list_clone = test_list * 1
test_list_clone[0] = 77
test_list_clone[2][-1] = 77
print(test_list)
print(test_list_clone)
``````

Output:

[11, 2, [3, 6, 77], 4, 5]

[77, 2, [3, 6, 77], 4, 5]

## Copy list with copy package

Fortunately, a copy package is built in Python to do the shadow copy and deep copy for us.

``````import copy

test_list_clone = copy.copy(test_list)
test_list_clone[0] = 88
test_list_clone[2][-1] = 88
print(test_list)
print(test_list_clone)
``````

Output:

[11, 2, [3, 6, 88], 4, 5]

[88, 2, [3, 6, 88], 4, 5]

### Deep copy

``````test_list_clone = copy.deepcopy(test_list)
test_list_clone[0] = 99
test_list_clone[2][-1] = 99
print(test_list)
print(test_list_clone)
``````

Output:

[11, 2, [3, 6, 88], 4, 5]

[99, 2, [3, 6, 99], 4, 5]

Finally, we got a way to do the deep copy for the nested list. Now, the nested list is modified without affecting the original list content.