Python: Append a list to another list and Clear the first list

Question:

Consider this example at the REPL:

>>> list1 = [1, 2, 3]
>>> list2 = []
>>> list2.append(list1)
>>> list1
[1, 2, 3]
>>> list2
[[1, 2, 3]]
>>> del list1[:]
>>> list1
[]
>>> list2
[[]]

When I clear list1 using del list1[:], the contents of list2 are also cleared. Why does this happen?

Asked By: kskp

||

Answers:

Passing a list to a method like append is just passing a reference to the same list referred to by list1, so that’s what gets appended to list2. They’re still the same list, just referenced from two different places.

If you want to cut the tie between them, either:

  1. Insert a copy of list1, not list1 itself, e.g. list2.append(list1[:]), or
  2. Replace list1 with a fresh list after appending instead of clearing in place, changing del list1[:] to list1 = []

Note: It’s a little unclear, but if you want the contents of list1 to be added to list2 (so list2 should become [1, 2, 3] not [[1, 2, 3]] with the values in the nested list), you’d want to call list2.extend(list1), not append, and in that case, no shallow copies are needed; the values from list1 at that time would be individually appended, and no further tie would exist between list1 and list2 (since the values are immutable ints; if they were mutable, say, nested lists, dicts, etc., you’d need to copy them to completely sever the tie, e.g. with copy.deepcopy for complex nested structure).

Answered By: ShadowRanger

So basically here is what the code is doing:

Before delete

enter image description here

After deleting

enter image description here

In short, both lists names are pointing to the same list object.

code visualization source

Answered By: Aziz Alto

The same problem happened with me as well.

original_list = ["a.csv", "b.csv"]                
copied_list = original_list
original_list.clear()

When I do so, both the lists (original_list and copied_list) get cleared. What worked for me as a solution of it,

original_list = ["a.csv", "b.csv"]                
copied_list  = original_list
original_list = [] # original_list  is refreshed with a fresh list.

This too also works,

original_list = ["a.csv", "b.csv"]
copied_list = original_list[:]

Thanks to @ShadowRanger.

Answered By: Sarvesh Pandey
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.