4

If I have a set of loops like this:

x = [[...],[...],[...]]    

for a in x[0]:
  for b in x[1]:
    for c in x[2]:
      # Do something with a,b,c

Is there a simple way to simplify it, especially if there are more levels to it? It seems like something quite easy to do, but I just can't figure it out.

JJJollyjim
  • 5,837
  • 19
  • 56
  • 78

1 Answers1

7

It's quite easy with the itertools library.

for x, y, z in itertools.product(a, b, c):
    print x, y, z

How itertools.product could be implemented:

def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)

Example:

In [1]: a = range(2)    
In [2]: b = range(2, 4)
In [3]: c = range(4, 6)
In [4]: import itertools
In [5]: list(itertools.product(a, b, c))
Out[5]: 
[(0, 2, 4),
 (0, 2, 5),
 (0, 3, 4),
 (0, 3, 5),
 (1, 2, 4),
 (1, 2, 5),
 (1, 3, 4),
 (1, 3, 5)]

In [6]: for x, y, z in itertools.product(a, b, c):
   ...:     print 'x: %d, y: %d, z: %d' % (x, y, z)
   ...: 
x: 0, y: 2, z: 4
x: 0, y: 2, z: 5
x: 0, y: 3, z: 4
x: 0, y: 3, z: 5
x: 1, y: 2, z: 4
x: 1, y: 2, z: 5
x: 1, y: 3, z: 4
x: 1, y: 3, z: 5
Kelsius
  • 433
  • 2
  • 5
  • 19
Wolph
  • 78,177
  • 11
  • 137
  • 148