Pythonic way of iterating over 3D array

arrays, loops, python

Solution

Have a look at itertools, especially itertools.product. You can compress the three loops into one with

import itertools

for x, y, z in itertools.product(*map(xrange, (x_dim, y_dim, z_dim)):
    ...

You can also create the cube this way:

cube = numpy.array(list(itertools.product((0,1), (0,1), (0,1))))
print cube
array([[0, 0, 0],
       [0, 0, 1],
       [0, 1, 0],
       [0, 1, 1],
       [1, 0, 0],
       [1, 0, 1],
       [1, 1, 0],
       [1, 1, 1]])

and add the offsets by a simple addition

print cube + (10,100,1000)
array([[  10,  100, 1000],
       [  10,  100, 1001],
       [  10,  101, 1000],
       [  10,  101, 1001],
       [  11,  100, 1000],
       [  11,  100, 1001],
       [  11,  101, 1000],
       [  11,  101, 1001]])

which would to translate to `cube + (x,y,z)` in your case. The very compact version of your code would be

import itertools, numpy

cube = numpy.array(list(itertools.product((0,1), (0,1), (0,1))))

x_dim = y_dim = z_dim = 10

for offset in itertools.product(*map(xrange, (x_dim, y_dim, z_dim))):
    work_with_cube(cube+offset)

Edit: `itertools.product` makes the product over the different arguments, i.e. `itertools.product(a,b,c)`, so I have to pass `map(xrange, ...)` with as `*map(...)`

Problem

I have a 3D array in Python and I need to iterate over all the cubes in the array. That is, for all `(x,y,z)` in the array's dimensions I need to access the cube: ``` array[(x + 0, y + 0, z + 0)] array[(x + 1, y + 0, z + 0)] array[(x + 0, y + 1, z + 0)] array[(x + 1, y + 1, z + 0)] array[(x + 0, y + 0, z + 1)] array[(x + 1, y + 0, z + 1)] array[(x + 0, y + 1, z + 1)] array[(x + 1, y + 1, z + 1)] ``` The array is a Numpy array, though that's not really necessary. I just found it very easy to read the data in with a one-liner using `numpy.fromfile()`. Is there any more Pythonic way to iterate over these than the following? That simply looks like C using Python syntax. ``` for x in range(x_dimension): for y in range(y_dimension): for z in range(z_dimension): work_with_cube(array[(x + 0, y + 0, z + 0)], array[(x + 1, y + 0, z + 0)], array[(x + 0, y + 1, z + 0)], array[(x + 1, y + 1, z + 0)], array[(x + 0, y + 0, z + 1)], array[(x + 1, y + 0, z + 1)], array[(x + 0, y + 1, z + 1)], array[(x + 1, y + 1, z + 1)]) ```

Original source

Related problems