Generator question

Peter Otten __peter__ at web.de
Thu Mar 14 05:45:25 EDT 2019


Pierre Reinbold wrote:

> Wow, thank you Ian for this very detailed answer, and thank you for taking
> the time for that! Much appreciated!
> 
> If I get this right, I have to somehow fix the value of a_list during the
> loop, like when you use the classic default value argument trick with
> lambdas (damn, I should have thought of that!). So if I "unfold" the
> generator expression, using default values for both iterables, I get this
> :
> 
> def flat_gen_cat_prod(lists):
>     solutions = [[]]
>     for a_list in lists:
>         def new_solutions(l=a_list, s=solutions):
>             for part_sol in s:
>                 for el in l:
>                     yield part_sol+[el]
>         solutions = new_solutions()
>     return solutions
> 
> With this I get the right behavior! Thanks again!
> 
> Doest that mean that there is no possibility to use a generator expression
> in this case ? (gen. exp. are sooo much more elegant :-))

The obvious approach is to put the genexpr into a function:

def prod(lists):
    solutions = [[]]
    def new_solutions(a_list):
        return (part_sol + [el] for part_sol in solutions for el in a_list)

    for a_list in lists:
        solutions = new_solutions(a_list)
    return solutions

If you want to avoid the function you can take advantage of the fact that 
the outermost iterable is bound early:

def prod(lists):
    solutions = [[]]

    for a_list in lists:
        solutions = (
            part_sol + [el]
            for solutions, a_list in [(solutions, a_list)]
            for part_sol in solutions for el in a_list
        )
    return solutions





More information about the Python-list mailing list