0

Help! I have a big problem using Python. We know in Python if A=[1,2,3] and if B=A, B[1]=10, then A=[1,10,3]. To fix this, we can import copy and B =copy.copy(A) or B=A[:]. In both cases, doing B[1]=10 won't change A.

Now I extend A as a dictionary, and A[1]=[1,2,3]. Doing

  A = {1:[1,2,3]}
  A[2] = A[1][:]
  for j in range(len(A[1])):
      A[2].append(4)
  print (A[2])
  print (A[1])

the result shows

  [1, 2, 3, 4, 4, 4]
  [1, 2, 3]

It only changes A[2], not A[1]. So it is good. But If I do A[1] = [[1],[2],[3]], and

  A = {1:[[1],[2],[3]]}
  A[2] = A[1][:]
  for j in range(len(A[1])):
      A[2][j].append(4)    
  print (A[2])
  print (A[1])

which instead gives me

  [[1, 4], [2, 4], [3, 4]]
  [[1, 4], [2, 4], [3, 4]]

not

  [[1, 4], [2, 4], [3, 4]]
  [[1], [2], [3]]

where A[1] was changed. Anyone can help me figure this out? I even use A[2] = copy.copy(A[1]) still doesn't work. Thank you very much for the solution!!!!

TripleH
  • 447
  • 7
  • 16

1 Answers1

1

The explantation for this behavior is that you're only copying at the first level. When you set up your dictionary as

>>> A = {1:[[1],[2],[3]]}
>>> A[2] = A[1][:]

then A[2] is an independent copy of A[1] only at the first level (id gives the memory address of an object):

>>> id(A[1])
4347137160
>>> id(A[2])
4347154056

However, respective elements of A[1] and A[2] are still references to the same object:

>>> id(A[1][0])
4346993992
>>> id(A[2][0])
4346993992

As pointed out in other comments, you would have to make a deepcopy to also copy at the second level:

>>> import copy
>>> A[2] = copy.deepcopy(A[1])
>>> id(A[1][0])
4346993992
>>> id(A[2][0])
4349177096
Michael Goerz
  • 4,300
  • 3
  • 23
  • 31