Issue
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:
- Why doesn't
list(product(array)) == list(product(l1,l2,l3))
? - Using
array
, how can I get the same output aslist(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):
.
Solution
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
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.