2

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']]

Vedant Modi
  • 115
  • 2
  • 11
  • You might need to use deepcopy instead of just copy – mama Aug 09 '21 at 12:57
  • 1
    `from copy import deepcopy`. Use this function instead. – Mathieu Aug 09 '21 at 12:57
  • 2
    @MB-F Not the best duplicate since the OP here already made a shallow copy which is the correct solution to the question you linked. – user2390182 Aug 09 '21 at 13:10
  • @schwobaseggl You are right, though the answer is very thorough and covers the case of this question too. I think it makes sense to have it linked for more information while your answer here directly solves the specific problem. – MB-F Aug 09 '21 at 13:29

3 Answers3

2

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.

user2390182
  • 72,016
  • 6
  • 67
  • 89
1

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)
1

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?

shoaib30
  • 877
  • 11
  • 24