0

Suppose there are 2 categories if items: cat_1 = [1, 2], cat_2 = ['a', 'b'], then I should get (1, 'a'), ('1', 'b'), (2, 'a'), (2, 'b'). And if there is one more categories of items cat_3 = ['x', 'y'], then the result should be (1, 'a', 'x'), (1, 'a', 'y'), ... (2, 'b', 'y').

It's easy to get all combination if the number of categories is a constant value, one can just get all combination by

[(i,j) for i in cat_1 for j in cat_2]

But I don't know what's the pythonic way to implement a function to generate all possible combination of various categories of items.

link89
  • 1,064
  • 10
  • 13
  • 2
    You might want to look at the [itertools](https://docs.python.org/3/library/itertools.html), for example the `product()` and `combinations()`. – Niko Föhr Mar 08 '23 at 12:34
  • 1
    I've included a simple re-implementation in the linked question, if that's what you were looking for: https://stackoverflow.com/a/75673244/671543 – njzk2 Mar 08 '23 at 12:50

1 Answers1

-1

You could use itertools.product to get the set of combinations, and using globals() in combination with a list comprehension to get a list of all categories (assuming they are all in the format cat_i):

from itertools import product

cat_1 = [1, 2]
cat_2 = ['a', 'b']
cat_3 = ['x', 'y']

cat_list = [globals()[cat] for cat in [f"cat_{i+1}" for i in range(3)]]

print(list(product(*cat_list)))

Output:

[(1, 'a', 'x'), (1, 'a', 'y'), (1, 'b', 'x'), (1, 'b', 'y'), (2, 'a', 'x'), (2, 'a', 'y'), (2, 'b', 'x'), (2, 'b', 'y')]

The only thing you would need to change is the range over which you loop. If that's still not what you'd want, you can use a try except block using itertools.count which counts forever:

from itertools import product, count

cat_1 = [1, 2]
cat_2 = ['a', 'b']
cat_3 = ['x', 'y']

cat_list = []

for i in count(start=1):
    try:
        cat_list.append([globals()[f"cat_{i}"]])
    except KeyError:
        break

print(list(product(*cat_list)))

So categories get added until one doesn't exist, and then it stops.

B Remmelzwaal
  • 1,581
  • 2
  • 4
  • 11