Esse Ti
Esse Ti

Reputation: 5

Combinations of elements of different lists satisfying a condition

Here is an example of the input and afterwards of what I would like to achieve:

a = [1,2,3,4]
b = [2,3,6,8]
c = [4,7,8,9]
d = [4,8,9,10]

My objective is to find all the combinations of n elements such that the result contains one or more element of each list.

An example of result with n=3.

 res = [[1,3,8],[2,3,8],...etc.]

The only way I have found till now is using a comparison, for sure really odd and slow.

Any help would be so appreciated.

Upvotes: 0

Views: 749

Answers (1)

boot-scootin
boot-scootin

Reputation: 12515

>>> import itertools
>>> all_elements = {x for y in [a, b, c, d] for x in y}
>>> all_elements
{1, 2, 3, 4, 6, 7, 8, 9, 10}
>>> n = 3
# Find all n combinations of a set of the elements in all lists
>>> combos = set(itertools.combinations(all_elements, n))
>>> combos
{(3, 4, 6), (1, 4, 7), (1, 2, 8), (3, 8, 10), (2, 6, 9), (3, 6, 10), (3, 4, 7), (2, 3, 6), (1, 2, 9), (4, 6, 9), (2, 6, 8), (6, 8, 9), (1, 8, 9), (1, 2, 10), (2, 3, 7), (4, 6, 8), (7, 9, 10), (3, 6, 8), (4, 8, 10), (3, 6, 9), (1, 6, 8), (4, 6, 10), (4, 8, 9), (6, 8, 10), (2, 6, 7), (1, 7, 8), (1, 6, 9), (4, 7, 10), (6, 9, 10), (1, 6, 10), (3, 9, 10), (1, 8, 10), (2, 8, 9), (4, 7, 8), (3, 6, 7), (1, 3, 10), (4, 7, 9), (2, 7, 8), (1, 3, 9), (2, 4, 7), (3, 4, 8), (2, 7, 9), (1, 3, 8), (2, 4, 6), (2, 8, 10), (3, 4, 9), (1, 2, 3), (1, 6, 7), (2, 7, 10), (6, 7, 8), (7, 8, 9), (3, 4, 10), (6, 7, 9), (1, 2, 4), (2, 3, 4), (2, 9, 10), (7, 8, 10), (4, 9, 10), (6, 7, 10), (1, 4, 10), (2, 3, 8), (8, 9, 10), (1, 3, 7), (2, 4, 9), (1, 2, 6), (2, 3, 9), (3, 7, 9), (2, 4, 10), (1, 3, 6), (1, 7, 10), (1, 2, 7), (1, 4, 8), (2, 3, 10), (2, 4, 8), (1, 9, 10), (1, 7, 9), (3, 7, 8), (1, 4, 9), (1, 3, 4), (3, 8, 9), (1, 4, 6), (3, 7, 10), (4, 6, 7), (2, 6, 10)}

Here's the good stuff. This comprehension will keep only those combinations for which the condition is satisfied that every list in [a, b, c, d] contains at least one element from the combination:

>>> res = {com for com in combos if all(any(val in arr for val in com) for arr in [a, b, c, d])}

Check it out:

>>> res
{(3, 4, 6), (3, 8, 10), (1, 2, 8), (2, 6, 9), (3, 4, 7), (1, 2, 9), (4, 6, 9), (2, 6, 8), (1, 8, 9), (4, 6, 8), (1, 4, 6), (3, 6, 8), (4, 8, 10), (3, 6, 9), (1, 6, 8), (4, 6, 10), (4, 8, 9), (1, 6, 9), (3, 9, 10), (1, 3, 4), (2, 8, 9), (4, 7, 8), (2, 7, 8), (1, 3, 9), (2, 4, 7), (3, 4, 8), (2, 7, 9), (1, 3, 8), (2, 4, 6), (2, 8, 10), (3, 4, 9), (2, 7, 10), (3, 4, 10), (1, 2, 4), (2, 3, 4), (2, 9, 10), (2, 3, 8), (2, 4, 9), (2, 3, 9), (3, 7, 9), (2, 4, 10), (2, 4, 8), (1, 4, 8), (3, 7, 8), (1, 7, 8), (3, 8, 9), (1, 8, 10), (3, 7, 10), (4, 6, 7)}

Upvotes: 1

Related Questions