92

X is a 2D array. I want to have a new variable Y that which has the same value as the array X. Moreover, any further manipulations with Y should not influence the value of the X.

It seems to me so natural to use y = x. But it does not work with arrays. If I do it this way and then changes y, the x will be changed too. I found out that the problem can be solved like that: y = x[:]

But it does not work with 2D array. For example:

x = [[1,2],[3,4]]
y = x[:]
y[0][0]= 1000
print x

returns [ [1000, 2], [3, 4] ]. It also does not help if I replace y=x[:] by y = x[:][:].

Does anybody know what is a proper and simple way to do it?

Roman
  • 124,451
  • 167
  • 349
  • 456

5 Answers5

130

Using deepcopy() or copy() is a good solution. For a simple 2D-array case

y = [row[:] for row in x]
Ryan Ye
  • 3,159
  • 1
  • 22
  • 26
87

Try this:

from copy import copy, deepcopy
y = deepcopy(x)

I'm not sure, maybe copy() is sufficient.

Constantinius
  • 34,183
  • 8
  • 77
  • 85
14

For 2D arrays it's possible use map function:

old_array = [[2, 3], [4, 5]]
# python2.*
new_array = map(list, old_array)
# python3.*
new_array = list(map(list, old_array))
1

In your case(since you use list of lists) you have to use deepcopy, because 'The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances): A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original. A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.'

Note that sample below is simply intended to show you an example(don't beat me to much) how deepcopy could be implemented for 1d and 2d arrays:

arr = [[1,2],[3,4]]

deepcopy1d2d = lambda lVals: [x if not isinstance(x, list) else x[:] for x in lVals]

dst = deepcopy1d2d(arr)

dst[1][1]=150
print dst
print arr
Artsiom Rudzenka
  • 27,895
  • 4
  • 34
  • 52
  • 1
    "you have to use deepcopy" Not really. There's always a more complicated, but (maybe) faster way. See Ryan Ye's answer. Yours is fine, but this statement is not perfect. – palsch Jan 02 '16 at 20:02
  • @palsch as i can see there is no difference between our answers. Mine deepcopy1d2d doing the same and even more)))) – Artsiom Rudzenka Jan 04 '16 at 04:42
0

I think np.tile also might be useful

>>> a = np.array([0, 1, 2])
>>> np.tile(a, 2)
array([0, 1, 2, 0, 1, 2])
>>> np.tile(a, (2, 2))
array([[0, 1, 2, 0, 1, 2],
       [0, 1, 2, 0, 1, 2]])
>>> np.tile(a, (2, 1, 2))
array([[[0, 1, 2, 0, 1, 2]],
       [[0, 1, 2, 0, 1, 2]]])
Anoop Toffy
  • 918
  • 1
  • 9
  • 22