When playing around with generators, I too found a version of itertools.product
, and it is almost as fast as the (native) library version, while being 100% compatible with it, and it does not build intermediate results:
def product(*args, **kwds):
"Alternative fast implementation of product for python < 2.6"
def cycle(values, uplevel):
for prefix in uplevel: # cycle through all upper levels
for current in values: # restart iteration of current level
yield prefix + (current,)
stack = (),
for level in tuple(map(tuple, args)) * kwds.get('repeat', 1):
stack = cycle(level, stack) # build stack of iterators
return stack
With python 2.7.3, I found the performance to be really good (usually only about a factor of 5-10 slower with essentially the same memory usage).
>>> import itertools as itt
>>> timeit for _ in itt.product(range(20), range(3), range(150)): pass
1000 loops, best of 3: 221 µs per loop
>>> timeit for _ in product(range(20), range(3), range(150)): pass
1000 loops, best of 3: 1.14 ms per loop
EDIT: made code even simpler and Python 3-ready.