Neater way of making indexes?

Bengt Richter bokr at oz.net
Sat May 31 04:13:45 EDT 2003


On 30 May 2003 18:09:20 -0700, janeaustine50 at hotmail.com (Jane Austine) wrote:

>The function returns a list of ordered indexes for nested for-loops of
>given input ranges.
>
>>>> from itertools import *
>>>> def indexes(upto):
>    multi=lambda alist:reduce(lambda x,y:x*y,alist,1)
>    g=[ cycle(chain(*[repeat(each,multi(upto[i+1:])) for each in
>range(upto[i])]))
>        for i in range(len(upto))]
>    return list(islice(izip(*g),multi(upto)))
>
>>>> indexes((4,))
>[(0,), (1,), (2,), (3,)]
>>>> indexes((3,2,4))
>[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 1, 0), (0, 1, 1), (0,
>1, 2), (0, 1, 3), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 0, 3), (1, 1,
>0), (1, 1, 1), (1, 1, 2), (1, 1, 3), (2, 0, 0), (2, 0, 1), (2, 0, 2),
>(2, 0, 3), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 1, 3)]
>
>I don't like this code too much. Any suggestions?
>

 >>> def indexes(*tops):
 ...     def tuto(tups, *tops):
 ...         if not tops: return tups
 ...         return tuto([(i,)+ t for i in xrange(tops[-1]) for t in tups], *tops[:-1])
 ...     return tuto([()], *tops)
 ...
 >>> indexes(2,3)
 [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
 >>> for t in indexes(2,3,4): print t
 ...
 (0, 0, 0)
 (0, 0, 1)
 (0, 0, 2)
 (0, 0, 3)
 (0, 1, 0)
 (0, 1, 1)
 (0, 1, 2)
 (0, 1, 3)
 (0, 2, 0)
 (0, 2, 1)
 (0, 2, 2)
 (0, 2, 3)
 (1, 0, 0)
 (1, 0, 1)
 (1, 0, 2)
 (1, 0, 3)
 (1, 1, 0)
 (1, 1, 1)
 (1, 1, 2)
 (1, 1, 3)
 (1, 2, 0)
 (1, 2, 1)
 (1, 2, 2)
 (1, 2, 3)

Regards,
Bengt Richter




More information about the Python-list mailing list