nickamcarthur - 1 month ago 4
Python Question

# Converting 3 dimension array into 1 dimensional list in python

I am trying to take characters from a file and store them in a 3 dimensional array but to do this I need to convert the 3 dimensional array index into a single index.

I looked up how to do this and for this

``````def convert(file, w, h):
pix = [[["", "", ""] for x in range(w)] for y in range(h)]
for x in range(w):
for y in range(h):
for c in range(3):
pix[x][y][c] = ord(file[(x * w * h) + (y * h) + c])
return pix
``````

However

``````file[(x * w * h) + (y * h) + c]
``````

Is not giving me the correct values.

w and h change depending on the text file, but the third dimension is always 3 deep.

How can I do this?

I believe the following is correct:

``````def convert(file, w, h):
pix = [[["", "", ""] for y in range(h)] for x in range(w)]
for x in range(w):
for y in range(h):
for c in range(3):
pix[x][y][c] = ord(file[(x * h * 3) + (y * 3) + c])
return pix
``````

First, I changed the order of the comprehension loops in `pix` to match the loop below. Next, I changed the indexing of `file`. Note that when `x` and `y` are both `0`, you'll pick up elements `0`, `1` and `2` because that is the range of `c`. The next element that you want to pick up is `3` (when `x = 0, y = 1, c = 0`). The only way for that to happen is if you multiply `y` by `3`. We can then apply the same logic to see that we need to multiply `x` by `h` and `3` (since those are the sizes of the "faster" running dimensions).

Note that for things like this, `numpy` is really nice:

``````import numpy as np
print(np.reshape(range(36), (3, 4, 3)))
``````

Of course, this doesn't convert the characters to integers based on their ordinal -- but that's easy enough to do in pre-processing:

``````pix = np.reshape([ord(c) for c in file], (3, 4, 3))
``````

As a bonus, then you get to work with `pix` as a `numpy` array instead of as a list of list of list...