Product of multiple lists–individual lists vs array of lists, need help understanding

Question:

Forewarning: I’m new to Python and I’m teaching myself, so this question may just have a trivial solution–any help (and patience) is very much appreciated!

Okay, big picture is that I want to get the union of all possible intersections of a variable number of lists. I’m not really sure how to explain the general-case problem I’m running into, so for the sake of this question, I’ll just use an example with 3 lists (but again, the actual number of lists will vary):

Suppose we have the following:

>>>from itertools import product

>>>l1=[1,2,3]
>>>l2=[1,4,5]
>>>l3=[1,6,7]
>>>
>>>array=[l1,l2,l3]
>>>
>>>
>>>list(product(array))
[([1, 2, 3],), ([1, 4, 5],), ([1, 6, 7],)]
>>>
>>>list(product(l1,l2,l3)
[(1, 1, 1), (1, 1, 6), (1, 1, 7), (1, 4, 1), (1, 4, 6), (1, 4, 7), (1, 5, 1), (1, 5, 6), (1, 5, 7), (2, 1, 1), (2, 1, 6), (2, 1, 7), (2, 4, 1), (2, 4, 6), (2, 4, 7), (2, 5, 1), (2, 5, 6), (2, 5, 7), (3, 1, 1), (3, 1, 6), (3, 1, 7), (3, 4, 1), (3, 4, 6), (3, 4, 7), (3, 5, 1), (3, 5, 6), (3, 5, 7)]

My questions are:

  1. Why doesn’t list(product(array)) == list(product(l1,l2,l3))?
  2. Using array, how can I get the same output as list(product(l1,l2,l3))?

For more context:

Ultimately, the goal is to get the union of all possible combinations of the intersections of the lists. I.e.;

1>>>for x in product(l1,l2,l3):
...     newArray.append(reduce(set.intersection, [set(e) for e in array])
2>>>u=reduce(set.union, [set(e) for e in newArray])
3>>>u
set([1])

Except, because I don’t know how many lists I’ll have (in my code, they’re being appended onto array by a loop), I want line 1 to be something like for x in product(array):, not for x in product(l1,l2,l3):.

Asked By: Emm Gee

||

Answers:

1) Why doesn’t list(product(array))=list(product(l1,l2,l3))?

Well the itertools.product() takes in iterables and then produces the Cartesian product amongst them. So when you do list(product(array)) you are basically trying to take cartesian product of a single list(?) and notice the commas in the output of the same signifying cartesian product between one list and empty iterable.

2) Using array, how can I get the same output as list(product(l1,l2,l3))?

Notice your problem boils down to being to convert the arr list to *args while calling the function.We have the * operator for this, So for the answer just do:

product(*arr)

From the python documentation:

If the syntax *expression appears in the function call, expression
must evaluate to an iterable. Elements from this iterable are treated
as if they were additional positional arguments; if there are
positional arguments x1, …, xN, and expression evaluates to a
sequence y1, …, yM, this is equivalent to a call with M+N positional
arguments x1, …, xN, y1, …, yM.

Since you must mentioned that you are learning on your own,
this is also covered in the python tutorial, in a section titled Unpacking argument lists.

Answered By: Aviral Verma