0

Let's say I have the following elements: ['A', 'B', 1, 2]

My idea is to get the following combinations:

  • ('A', 1)
  • ('A', 2)
  • ('B', 1)
  • ('B', 2)

But these are not all the combinations of the above sequence, e.g. I'm not considering (in purpose) ('A', 'B') or (1, 2)

Using itertools.combinations, of course, gets me all the combinations:

from itertools import combinations

combinations(['A', 'B', 1, 2], 2)

# [('A', 'B'), ('A', 1), ('A', 2), ('B', 1), ('B', 2), (1, 2)]

It's possible for me to internally group the elements that cannot go together:

elems = [('A', 'B'), (1, 2)]

However, combinations does not expect iterables inside other iterables, so the outcome is not really unexpected: [(('A', 'B'), (1, 2))]. Not what I want, nonetheless.

What's the best way to achieve this?

Matias Cicero
  • 25,439
  • 13
  • 82
  • 154

2 Answers2

0

You can use itertools.product to get the cartesian product of two lists:

from itertools import product

elems = [('A', 'B'), (1, 2)]

list(product(*elems))
# [('A', 1), ('A', 2), ('B', 1), ('B', 2)]
user2390182
  • 72,016
  • 6
  • 67
  • 89
0

You can use itertools.product after forming new input with values grouped by type:

from itertools import product as prd, groupby as gb
d = ['A', 'B', 1, 2]
result = list(product(*[list(b) for _, b in gb(sorted(d, key=lambda x:str(type(x)), reverse=True), key=type)]))

Output:

[('A', 1), ('A', 2), ('B', 1), ('B', 2)]

This solution will create new sublists grouped by data type, enabling robustness for future input and/or flexibility in element ordering in d:

d = ['A', 1, 'B', 2, (1, 2), 'C', 3, (3, 4), (4, 5)]
result = list(prd(*[list(b) for _, b in gb(sorted(d, key=lambda x:str(type(x)), reverse=True), key=type)]))

Output:

[((1, 2), 'A', 1), ((1, 2), 'A', 2), ((1, 2), 'A', 3), ((1, 2), 'B', 1), ((1, 2), 'B', 2), ((1, 2), 'B', 3), ((1, 2), 'C', 1), ((1, 2), 'C', 2), ((1, 2), 'C', 3), ((3, 4), 'A', 1), ((3, 4), 'A', 2), ((3, 4), 'A', 3), ((3, 4), 'B', 1), ((3, 4), 'B', 2), ((3, 4), 'B', 3), ((3, 4), 'C', 1), ((3, 4), 'C', 2), ((3, 4), 'C', 3), ((4, 5), 'A', 1), ((4, 5), 'A', 2), ((4, 5), 'A', 3), ((4, 5), 'B', 1), ((4, 5), 'B', 2), ((4, 5), 'B', 3), ((4, 5), 'C', 1), ((4, 5), 'C', 2), ((4, 5), 'C', 3)]
Ajax1234
  • 69,937
  • 8
  • 61
  • 102