To elaborate on my comments, I'll try to recreate your list
In [202]: x=np.arange(10.)
In [223]: x
Out[223]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
In [224]: ll=[[[x]]] # a list
In [225]: ll[0] # still a list
Out[225]: [[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]]
In [226]: ll[0][0] # still a list
Out[226]: [array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]
In [227]: ll[0][0][0] # an array
Out[227]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
In [228]: ll[0][0][0][0] # a float
Out[228]: 0.0
In [229]: random.sample(ll,1) # same list nesting
Out[229]: [[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]]]
In [230]: y=np.copy(ll) # a 4d array
In [231]: y
Out[231]: array([[[[ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]]]])
In [232]: y.shape
Out[232]: (1, 1, 1, 10)
If ll
contained sublists of different sizes, we'll get an object array
In [233]: ll.append([[2]])
In [234]: ll
Out[234]: [[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]], [[2]]]
In [235]: random.sample(ll,2)
Out[235]: [[[2]], [[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]]]
In [236]: np.copy(ll)
Out[236]:
array([[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]],
[[2]]], dtype=object) # (2,1,1) shape
Playing around with this some more. If the np.copy
is a 4d array, then modifying an element of it does not modify ll
or x
. But if there is an intermediate object array level, then modifying y
will modify ll
and x
. It's more like making a shallow list copy (ll[:]
) as opposed to a deep copy.
In [270]: ll=[[[x]],[[1,2,3]]]
In [271]: ll
Out[271]: [[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]], [[1, 2, 3]]]
In [272]: y=np.copy(ll)
In [273]: y
Out[273]:
array([[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]],
[[1, 2, 3]]], dtype=object)
In [274]: y[0][0][0][0]=1
In [275]: y
Out[275]:
array([[[array([ 1., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]],
[[1, 2, 3]]], dtype=object)
In [276]: ll
Out[276]: [[[array([ 1., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]], [[1, 2, 3]]]
In [277]: x
Out[277]: array([ 1., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
In sum, np.copy
does not preserve the structure of nested lists of lists. It tries to make an array instead. What you should be using is copy.deepcopy
. That preserves the list structure, and copies values all the way down.