3

for instance consider the following:

a = [1,5,3,4]
b = a
a += [6]

after I append 6 to list a, it also appends it to list b, because they refer to each other (If I would've written b+=[6] instead, it would've produced the same result). What I need is to initialize list b to be the same as list a but not make it refer to list a.

Thank you!

4 Answers4

2

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

Deep copy a list in Python

Here is a article on shallow verse deep copying in python: https://docs.python.org/2/library/copy.html

Community
  • 1
  • 1
marsh
  • 2,592
  • 5
  • 29
  • 53
2

Use:

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 every dimension):

import copy

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

or:

b = list(a)
syntagma
  • 23,346
  • 16
  • 78
  • 134
1

You can make a copy of the list using:

b = list(a)
Daniel Reis
  • 12,944
  • 6
  • 43
  • 71
0

This is an explanation of exactly what happens and why you need deep copying sometimes. In python, some types of variables, such as lists, are stored slightly differently. When you assign a to [1, 5, 3, 4], what you are actually doing is assigning a to a pointer (something that tells you where that list is). When you say b = a, you assign b to a - which is a pointer. So they are both now the same pointer, pointing to the same place. Hence, when you change one, the other will change as well.

Now for the solution. There are 3 proposed solutions.

import copy
b = copy.deepcopy(a)
b = a[:]
b = list(a)

The first, doing a deep copy, will always work, but of course it's more effort than the other 2.

The second works because a[:] says "get me a list with all elements from a" (see list/string slicing in python), so it gets every item in a and puts it in b. The third method works exactly the same as the second. However, they have a problem when handling 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 here 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 over all the items in the list (the pointer to a second list), so we don't actually have our own second list - its the same pointer that a has. This is what deep copy does for you.

matts1
  • 857
  • 1
  • 9
  • 20