osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Generator question


Dear all,

I want to implement a function computing the Cartesian product if the elements
of a list of lists, but using generator expressions. I know that it is already
available in itertools but it is for the sake of understanding how things work.

I already have a working recursive version, and I'm quite sure that this
iterative version used to work (at least in some Python2.X) :

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

But, with Python3.7.2, all I got is this :

>>> list(flat_genexp_cat_prod([[1, 2], [3, 4], [5, 6]]))
[[5, 5, 5], [5, 5, 6], [5, 6, 5], [5, 6, 6], [6, 5, 5], [6, 5, 6], [6, 6, 5],
[6, 6, 6]]

instead of

>>> list(flat_genexp_cat_prod([[1, 2], [3, 4], [5, 6]]))
[[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5],
[2, 4, 6]]

Using a list comprehension instead of a generator expression solves the problem,
but I can't understand why the version above fails.

Even stranger, when debugging I tried to use itertools.tee to duplicate the
solutions generators and have a look at them :

def flat_genexp_cat_prod(lists):
    solutions = [[]]
    for a_list in lists:
        solutions, debug = tee(
		part_sol+[el] for part_sol in solutions for el in a_list)
        print("DEBUG", list(debug))
    return solutions

And, that version seems to work!

>>> list(flat_genexp_cat_prod([[1, 2], [3, 4], [5, 6]]))
DEBUG [[1], [2]]
DEBUG [[1, 3], [1, 4], [2, 3], [2, 4]]
DEBUG [[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4,
5], [2, 4, 6]]
[[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5],
[2, 4, 6]]

Can you help me understand what I'm doing wrong ?

Thank you by advance,


?r