All Articles Kinsa Creative

Python Deep Copy a List of Lists in Order to Avoid Making Edits to the Original Nested List Object

When copying a list of lists use deepcopy().

Python creates a reference to a list when assigning it to a new variable:

>>> list_1 = [1, 2, 3, 4]
>>> # assign list_1 to a new variable, list_2
>>> list_2 = list_1
>>> # change the first element in the referenced list
>>> list_2[0] = 5
>>> # the first list will reflect the change
>>> list_1
[5, 2, 3, 4]
>>> list_2
[5, 2, 3, 4]

This can generally be gotten around by creating a copy of the list instead of just assigning it to a new variable, when this is done, changes to the second instance of the list are unique and the first instance remains unaffected:

>>> list_1 = [1, 2, 3, 4]
>>> # create list_2 as a copy of list_1 
>>> list_2 = list_1[:]
>>> # change the first element in the copied list
>>> list_2[0] = 5
>>> # the first list will remain the same
>>> list_1
[1, 2, 3, 4]
>>> list_2
[5, 2, 3, 4]

When the list is comprised of other lists, a copy of the outer list is made, however, the inner lists continue to contain references to the original and changes to the copied inner list will be reflected in the original:

>>> list_1 = [[1, 2, 3, 4], [5, 6, 7, 8]]
>>> # create list_2 as a copy of list_1 
>>> list_2 = list_1[:]
>>> # change the first outer element in the copied list
>>> list_2[0] = 5
>>> # the first list will remain the same
>>> list_1
[[1, 2, 3, 4], [5, 6, 7, 8]]
>>> list_2
[5, [5, 6, 7, 8]]
>>> # change the first element of the nested list in the copied list
>>> list_2[1][0] = 'a'
>>> # the first list will reflect the change 
>>> list_1
[[1, 2, 3, 4], ['a', 6, 7, 8]]
>>> list_2
[5, ['a', 6, 7, 8]]

Since the outer list contains objects (the inner list, or nested list, is an object) a deep copy is required in order to safely make edits to the nested list without those changes being reflected in the original:

>>> import copy
>>> list_1 = [[1, 2, 3, 4], [5, 6, 7, 8]]
>>> # create list_2 as a deep copy of list_1 
>>> list_2 = copy.deepcopy(list_1)
>>> # change the first outer element in the deep-copied list
>>> list_2[0] = 5
>>> # the first list will remain the same
>>> list_1
[[1, 2, 3, 4], [5, 6, 7, 8]]
>>> list_2
[5, [5, 6, 7, 8]]
>>> # change the first element of the nested list in the copied list
>>> list_2[1][0] = 'a'
>>> # the first list will still remain the same
>>> list_1
[[1, 2, 3, 4], [5, 6, 7, 8]]
>>> list_2
[5, ['a', 6, 7, 8]]

Slicing the whole of the original list to make a copy (list_2 = list_1[:]) or calling the list() function on the original list to make a copy (list_2 = list(list_1)) will have the same effect as calling copy.copy() on it to make the copy.

Feedback?

Email us at enquiries@kinsa.cc.