On Python, range(3) will return [0,1,2]. Is there an equivalent for multidimensional ranges?
range((3,2)) # [(0,0),(0,1),(1,0),(1,1),(2,0),(2,1)]
So, for example, looping though the tiles of a rectangular area on a tile-based game could be written as:
for x,y in range((3,2)):
Note I'm not asking for an implementation. I would like to know if this is a recognized pattern and if there is a built-in function on Python or it's standard/common libraries.
In numpy, it's
numpy.ndindex
. Also have a look atnumpy.ndenumerate
.E.g.
This yields:
I would take a look at
numpy.meshgrid
:http://docs.scipy.org/doc/numpy-1.6.0/reference/generated/numpy.meshgrid.html
which will give you the X and Y grid values at each position in a mesh/grid. Then you could do something like:
or
Numpy's
ndindex()
works for the example you gave, but it doesn't serve all use cases. Unlike Python's built-inrange()
, which permits both an arbitrarystart
,stop
, andstep
, numpy'snp.ndindex()
only accepts astop
. (Thestart
is presumed to be(0,0,...)
, and thestep
is(1,1,...)
.)Here's an implementation that acts more like the built-in
range()
function. That is, it permits arbitrarystart
/stop
/step
arguments, but it works on tuples instead of mere integers.Example:
You could use
itertools.product()
:The multiple repeated
xrange()
statements could be expressed like so, if you want to scale this up to a ten-dimensional loop or something similarly ridiculous:Which loops over ten variables, varying from
(0,0,0,0,0,0,0,0,0,0)
to(2,2,2,2,2,2,2,2,2,2)
.In general
itertools
is an insanely awesome module. In the same way regexps are vastly more expressive than "plain" string methods,itertools
is a very elegant way of expressing complex loops. You owe it to yourself to read theitertools
module documentation. It will make your life more fun.You can use
product
fromitertools
module.That is the cartesian product of two lists therefore:
gives this output: