Changes made in Python list showing up in copy of original list

Viewed 497

I'm making some changes to a list, however, these changes are being reflected in the copy of the original list.

I tried using these methods: copy_list = list(org_list), copy_list = org_list[:], copy_list = org_list.copy() They didn't work.

Here's my code followed by the output. Where am I going wrong?

name = ['A', 'B', 'C', 'D', 'E']
desc = [["1"], ['1', '2'], [], ['1', '2'], []]

desc1 = desc.copy()

for n, d in zip(name, desc):
    d.insert(0, n)

print(desc1)

Output (the alphabets shouldn't be visible): [['A', '1'], ['B', '1', '2'], ['C'], ['D', '1', '2'], ['E']]

3 Answers

Use copy.deepcopy:

from copy import deepcopy

desc1 = deepcopy(desc)

list.copy only makes a shallow copy: a new list object, but its elements (here mutable sublists) will be references to the same objects as the elements of the original.

The issue is that desc1 is a copy of desc but the lists inside desc are not copied, they are the same. Code to verify that -

name = ['A', 'B', 'C', 'D', 'E']
desc = [["1"], ['1', '2'], [], ['1', '2'], []]

desc1 = desc.copy()

print(desc1 is desc)
print(desc1[0] is desc[0])

Output:

False
True

To solve that you could use deepcopy as suggested by @schwobaseggl or

name = ['A', 'B', 'C', 'D', 'E']
desc = [["1"], ['1', '2'], [], ['1', '2'], []]

desc1 = [row.copy() for row in desc]

for n, d in zip(name, desc):
    d.insert(0, n)

print(desc1)

Create a copy of the list by default creates a shallow copy, which means the elements of the list are copied as-is into a new list. Native data types like int, str, bool etc will get copied but Complex data types like list, dict, object etc store only the pointer in the list. Hence when creating a copy() the pointer gets copied over.

Using copy.deepcopy() creates copies of each of the elements and sub-elements giving a true copy

from copy import deepcopy

name = ['A', 'B', 'C', 'D', 'E']
desc = [["1"], ['1', '2'], [], ['1', '2'], []]

desc1 = deepcopy(desc)

for n, d in zip(name, desc):
    d.insert(0, n)

print(desc1)

For more information: How to deep copy a list?

Related