nested for loop

Peter Otten __peter__ at web.de
Mon May 24 04:57:01 EDT 2004


Dan Bishop wrote:

> What you can do to make your code faster (if you don't change matr
> once it's created) is to precompute the 676 possible matrix rows.
> 
>    ELEMENT_RANGE = range(26)
>    MATRIX_ROWS = [[x, y] for x in ELEMENT_RANGE
>                          for y in ELEMENT_RANGE]
>    for row1 in MATRIX_ROWS:
>       for row2 in MATRIX_ROWS:
>          matr = [row1, row2]
> 
> That takes only 532 ms -- almost 3 times faster than the original.

Nice. Another speed gain (from 435 to 246ms on my machine) is in for you if
you use tuples instead of lists. And if you allow for somewhat less elegant
code that builds on your recipe,

from itertools import izip, repeat
ELEMENT_RANGE = range(26)
MATRIX_ROWS = [(x, y) for x in ELEMENT_RANGE
                        for y in ELEMENT_RANGE]
for row in MATRIX_ROWS:
    for matr in izip(repeat(row), MATRIX_ROWS):
        pass

you can bring that down to 138ms.

For the record: the straightforward solution (the original with tuples and
range() factored out)

r = range(26)
for a in r:
    for b in r:
        for c in r:
            for d in r:
                matr = ((a,b),(c,d))

takes 478ms. The "improved" variant is evil performance-wise (1598ms):

r = range(26)
for (a,b,c,d) in [(x,y,z,t)  for x in r
                             for y in r
                             for z in r
                             for t in r] :
   matr = ((a,b),(c,d))

It might be interesting how much this can be improved with 2.4's generator
expressions.

Peter




More information about the Python-list mailing list