multidimensional arrays
iteration techniques
n-dimensional loops
programming
algorithms

How to iterate over n dimensions?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Iterating over n dimensions means generating every valid coordinate in a shape such as (2, 3, 4) without hardcoding nested loops. The right solution depends on whether you want a general algorithm, a Python helper, or a library-specific iterator. The key idea is that an index in n dimensions is just a tuple of positions, one per axis.

The General Pattern

For a two-dimensional shape you might write:

python
for i in range(rows):
    for j in range(cols):
        ...

That works only because the number of dimensions is fixed at two. Once the dimension count is dynamic, you need a more general way to generate index tuples.

Use itertools.product in Python

For plain Python, the cleanest general approach is itertools.product:

python
1from itertools import product
2
3shape = (2, 3, 4)
4
5for index in product(*(range(size) for size in shape)):
6    print(index)

This prints:

text
1(0, 0, 0)
2(0, 0, 1)
3(0, 0, 2)
4...

Each index tuple is one coordinate in the full n-dimensional space. This is effectively the dynamic equivalent of nested loops.

Access Values in an N-Dimensional Structure

If you have a NumPy array, those generated index tuples can be used directly:

python
1import numpy as np
2from itertools import product
3
4array = np.arange(24).reshape(2, 3, 4)
5
6for index in product(*(range(size) for size in array.shape)):
7    print(index, array[index])

That makes the pattern practical, not just theoretical. You are iterating over every location and reading the corresponding value.

Use NumPy’s Built-In Helpers

When working with NumPy specifically, np.ndindex is even cleaner:

python
1import numpy as np
2
3array = np.arange(24).reshape(2, 3, 4)
4
5for index in np.ndindex(array.shape):
6    print(index, array[index])

This is one of the best answers when the data is already a NumPy array because it expresses the intent directly.

Another option is np.ndenumerate, which yields both the index and the value:

python
1import numpy as np
2
3array = np.arange(24).reshape(2, 3, 4)
4
5for index, value in np.ndenumerate(array):
6    print(index, value)

That is often the nicest form when you need both pieces together.

Recursive Generation for a Generic Algorithm

If you want to understand the algorithm from first principles, a recursive generator shows how dynamic nested loops work:

python
1def iterate_indices(shape, prefix=()):
2    if len(prefix) == len(shape):
3        yield prefix
4        return
5
6    axis = len(prefix)
7    for i in range(shape[axis]):
8        yield from iterate_indices(shape, prefix + (i,))
9
10
11for index in iterate_indices((2, 3, 2)):
12    print(index)

This recursively builds index tuples one axis at a time until the tuple reaches the same length as the shape.

It is not always the shortest solution in Python, but it makes the structure of the problem very clear.

Flat Iteration vs Coordinate Iteration

Sometimes you do not actually need the coordinate tuple. If you only need the values, a flat iterator may be simpler and faster.

Example with NumPy:

python
1import numpy as np
2
3array = np.arange(24).reshape(2, 3, 4)
4
5for value in array.flat:
6    print(value)

This loses the multidimensional index information, but it is useful when the location itself does not matter.

Performance Considerations

In numerical code, explicit Python-level iteration over every coordinate is often slower than vectorized operations. If your goal is transformation rather than inspection, try to use array operations first.

For example, instead of iterating to add one to every element:

python
array = array + 1

That is usually much better than touching each coordinate in Python.

So the real rule is:

  • iterate explicitly when you need per-index logic
  • prefer vectorized operations when the work applies uniformly

Common Pitfalls

The biggest pitfall is hardcoding nested loops for a fixed number of dimensions when the problem statement says the dimension count is dynamic. That code does not scale past the original case.

Another common mistake is iterating in Python over large numerical arrays when a library already has a vectorized solution. The code works, but it becomes slower than necessary.

People also often confuse shape values with valid indices. For a shape element 3, the valid index values are 0, 1, and 2, not 3.

Finally, be careful when mutating structures during iteration. The index-generation logic assumes the shape stays stable while you traverse it.

Summary

  • An n-dimensional iteration problem is really a problem of generating index tuples.
  • In plain Python, itertools.product is a clean general solution.
  • In NumPy, np.ndindex and np.ndenumerate are usually the best tools.
  • Recursive generators are useful for understanding the underlying algorithm.
  • Use explicit iteration only when you need per-index logic; otherwise prefer vectorized operations.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.