Python. How do I declare a list based on another list, but make sure they don't reference each other?
for example consider the following:
a = [1,5,3,4] b = a a += [6]
after adding 6 to list a, it also adds it to list b because they refer to each other (if I wrote b + = [6], it would produce the same result). I need to initialize list b to be the same as list a but not reference list a.
Thank!
source to share
You are doing what is called a shallow copy. You want to make a deep copy.
Here is an article on deep deep copying of verses in python: https://docs.python.org/2/library/copy.html
source to share
This is an explanation of what is happening and why you need deep copying. In python, some variable types, such as lists, are stored slightly differently. When you assign to a [1, 5, 3, 4]
, what you are actually doing is assignment to a pointer (which is what tells you where that list is). When you say b = a
you assign ba - which is a pointer. Thus, they are both the same pointer, pointing to the same place. Therefore, when you change one, the other also changes.
Now for a solution. There are 3 suggested solutions.
import copy b = copy.deepcopy(a) b = a[:] b = list(a)
The former, making a deep copy will always work, but of course it is more effort than the other 2.
The second works because it a[:]
says "Get a list with all the elements from a" (see the list / string section in python), so it gets each element in and puts it in b. The third method works exactly the same as the second. However, problems arise when processing multiple dimensions.
>>> a = [[1]]
>>> b=list(a) # or a[:], they do the same thing
>>> a[0].append(1)
>>> a.append(2)
>>> b
[[1, 1]]
>>> a
[[1, 1], 2]
The problem is that a is a pointer to a list, and the first item in that list is a pointer to a second list. With this method, we copy all the elements in the list (a pointer to the second list), so we don't actually have our own second list - its the same pointer as y. This is what deep copy does for you.
source to share