0

I wrote a function that should be recursively creating n-dimensional arrays that contain a value using nested lists, and on the surface, it is. (Dimensions is a tuple with the n-dimensional dimensions of the array i.e. (3,3,3) is a 3x3x3 array). However, the arrays my function creates have problems with assignment, as they are unable to assign a value to an individual index without also assigning that value to the other nested lists. And weirdly, when I declare an array of the same dimensions and values but using one line of nested lists, even though python states the objects are equal, assignment with the "manual" array, works just fine.

def createboard(dimensions,value):
    if dimensions[1:]:
        return dimensions[0]*[createboard(dimensions[1:],value)]
    else:
        return dimensions[0]*[value]

example = createboard((3,3,2),0)
print(example)
manual = [[[0, 0], [0, 0], [0, 0]],
    [[0, 0], [0, 0], [0, 0]],
    [[0, 0], [0, 0], [0, 0]]]
print(manual == example)
example[1][1][0] = True
print('example =', example)
manual[1][1][0] = True
print('example =', manual)

Outputs:

[[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
True
example = [[[True, 0], [True, 0], [True, 0]], [[True, 0], [True, 0], [True, 0]], [[True, 0], [True, 0], [True, 0]]]
example = [[[0, 0], [0, 0], [0, 0]], [[0, 0], [True, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]

Thanks for your help.

2 Answers2

0

Short answer: replace:

return dimensions[0]*[createboard(dimensions[1:],value)]

with:

return [createboard(dimensions[1:],value) for _ in range(dimensions[0])]

Note that the former makes only one recursive call, whereas the latter makes dimensions[0] recursive calls, which is much more expensive; but the latter actually creates dimensions[0] distinct lists, rather than reusing the same list several times.

Detailed explanation: List of lists changes reflected across sublists unexpectedly

Stef
  • 13,242
  • 2
  • 17
  • 28
0

After the call to the function, you can do

import numpy as np
example = np.array(example,copy=True).tolist()

This is because you are reusing the same object for the computation. However, if this is the case, you can substitute the original createboard by using numpy itself with

import numpy as np
example = np.ones(dimensions)*value
Hugo Guillen
  • 126
  • 6