This problem has been getting at me for a while now. Is there an easier way to write nested for
loops in python? For example if my code went something like this
Assuming each loop has some sort of independent meaning, break them out into named functions:
def do_tigers():
for x in range(3):
print something
def do_lions():
do_lionesses()
for x in range(3):
do_tigers()
def do_penguins():
for x in range(3):
do_lions()
..etc.
I could perhaps have chosen better names. 8-)
This is fairly common when looping over multidimensional spaces. My solution is:
xy_grid = [(x, y) for x in range(3) for y in range(3)]
for x, y in xy_grid:
# do something
for x1, y1 in xy_grid:
# do something else
From your code it looks like you want to perform an operation with every possible pair of points where x and y are in the range 0..2.
To do that:
for x1,y1,x2,y2 in itertools.product(range(3), repeat=4):
do_something_with_two_points(x1,y1,2,y2)
The operation do_something_with_two_points
will be called 81 times - once for every possible combination of points.
If you're frequently iterating over a Cartesian product like in your example, you might want to investigate Python 2.6's itertools.product -- or write your own if you're in an earlier Python.
from itertools import product
for y, x in product(range(3), repeat=2):
do_something()
for y1, x1 in product(range(3), repeat=2):
do_something_else()
Technically, you could use itertools.product
to get a cartesian product of N sequences, and iterate over that:
for y, x, y1, x1 in itertools.product(range(3), repeat=4):
do_something_else()
But I don't think that actually wins you anything readability-wise.
That way looks pretty straightforward and easy. Are you are saying you want to generalize to multiple layers of loops.... can you give a real-life example?
Another option I could think of would be to use a function to generate the parameters and then just apply them in a loop
def generate_params(n):
return itertools.product(range(n), range(n))
for x,y in generate_params(3):
do_something()