Generator (re-)definition within a loop

P

Pierre Reinbold

Hi all,

This is my first post on the list. I'm mainly a sysadmin and no expert
in programming languages, so this may be a stupid question but it
puzzles me.

I was pondering on the documentation of the function product(*args,
**kwds) in the itertools module. It is said that:

This function is equivalent to the following code, except that the
actual implementation does not build up intermediate results in memory:

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)

Ok, then what about using a generator expression instead of a list
comprehension to avoid generating the intermediate results in memory?

Letting the **kwds trick aside, it may give:

def genexp_product(*args):
pools = map(tuple, args)
result = [[]]
for pool in pools:
result = (x+[y] for x in result for y in pool)
for prod in result:
yield tuple(prod)

but this do not work as expected:
print list(product("ABC", "xy")) [('A', 'x'), ('A', 'y'), ('B', 'x'), ('B', 'y'), ('C', 'x'), ('C', 'y')]
print list(genexp_product("ABC", "xy"))
[('x', 'x'), ('x', 'y'), ('y', 'x'), ('y', 'y')]

My question is why ? What is the final generator "result" at the end of
the main loop in genexp_product ? How is it build exactly ? Is this an
effet of some sort of "lazy evaluation" ?

Thanks for your help in understanding this,

3.14r

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Members online

No members online now.