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!

+3


source to share


4 answers


You are doing what is called a shallow copy. You want to make a deep copy.

Deep copy a list in Python



Here is an article on deep deep copying of verses in python: https://docs.python.org/2/library/copy.html

+2


source


Using:

a = [1,5,3,4]
b = a[:] # <- this is where you need to add ':'
a += [6]

      

or copy.deepcopy()

(this solution is better for multidimensional lists, as it will create a copy for each dimension):



import copy

a = [1,5,3,4]
b = copy.deepcopy(a)
a += [6]

      

or

b = list(a)

      

+2


source


You can make a copy of the list using:

b = list(a)

      

+1


source


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.

0


source







All Articles