Same functionality as the itertools product method (http://docs.python.org/library/itertools.html#itertools.product) with one major difference: generators are executed as the loop executes. An itertools product causes all the variables to be collected before the loop actually starts looping.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | def recursiveLooper(iterators, pos=0):
""" Implements the same functionality as nested for loops, but is
more dynamic. iterators can either be a list of methods which
return iterables, a list of iterables, or a combination of both.
"""
nextLoop, v = None, []
try:
gen = iter(iterators[pos]())
except TypeError:
gen = iter(iterators[pos])
while True:
try:
yield v + nextLoop.next()
except (StopIteration, AttributeError):
v = [gen.next(),]
if pos < len(iterators) - 1:
nextLoop = recursiveLooper(iterators, pos + 1)
else:
yield v
# Some examples of how to use it:
def gen():
for x in [1, 2]:
yield x
for x in gen():
for y in gen():
for z in gen():
print x, y, z
print "-" * 10
for x, y, z in recursiveLooper([gen,] * 3):
print x, y, z
print "-" * 10
for x, y, z in recursiveLooper([[1, 2],] * 3):
print x, y, z
|
Actually, itertools.product doesn't collect the variables before looping. From http://docs.python.org/library/itertools.html#itertools.product: "the actual implementation does not build up intermediate results in memory".
Its good as academic toy. But not very usefull in production. Because its very slow.
And here is the code i used for this tests: http://pastie.textmate.org/1400002 Basically it's your code that is executed using timeit module (python standart module)