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?
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:
- Insert a copy of
list1
, not list1
itself, e.g. list2.append(list1[:])
, or
- Replace
list1
with a fresh list
after append
ing 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 append
ed, and no further tie would exist between list1
and list2
(since the values are immutable int
s; if they were mutable, say, nested list
s, dict
s, etc., you’d need to copy them to completely sever the tie, e.g. with copy.deepcopy
for complex nested structure).
So basically here is what the code is doing:
Before delete
After deleting
In short, both lists names are pointing to the same list object.
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.
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?
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:
- Insert a copy of
list1
, notlist1
itself, e.g.list2.append(list1[:])
, or - Replace
list1
with a freshlist
afterappend
ing instead of clearing in place, changingdel list1[:]
tolist1 = []
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 append
ed, and no further tie would exist between list1
and list2
(since the values are immutable int
s; if they were mutable, say, nested list
s, dict
s, etc., you’d need to copy them to completely sever the tie, e.g. with copy.deepcopy
for complex nested structure).
So basically here is what the code is doing:
Before delete
After deleting
In short, both lists names are pointing to the same list object.
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.