Generator (re-)definition within a loop

Pierre Reinbold pierre.reinbold at uclouvain.be
Fri Jun 18 15:57:48 EDT 2010


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



More information about the Python-list mailing list