1

What I'm looking for is a way to do the cartesian product n amount of times, similar to:

[(i_1,...,i_n) for i_1 in range(x) ... for i_n in range(x)]

I am supposed to build my own function for this. I know I can do something along the lines of:

[...[7, 5, 6], [7, 5, 7], ...]
[...[7, 5, 6, 1], [7, 5, 7, 2], ...]

But, I'm looking for a more elegant solution. In fact, I would like to know if there is a way to do it like the first line of code above.

  • I'd use the python libraries. – Peter Wood Mar 25 '21 at 19:13
  • @PeterWood not allowed, this is an exercise, supposed to build my own – AyamGorengPedes Mar 25 '21 at 19:25
  • As the `for` loops are over the same `range(x)` each time, this question is slightly different from the supposed duplicate. The solution would be [`itertools.product(range(x), repeat=n)`](https://docs.python.org/3.1/library/itertools.html?highlight=combinations#itertools.product) – Stuart Mar 25 '21 at 19:25
  • @Stuart in any case, supposed to build my own function – AyamGorengPedes Mar 25 '21 at 19:26
  • Check the question marked as duplicate - there are several answers that don't use the libraries. A simple recursive version: `def range_product(x, n): return [()] if n == 0 else [(i, ) + t for t in range_product(x, n-1) for i in range(x)]` – Stuart Mar 25 '21 at 19:51
  • @AyamGorengPedes well, you need to be specific in the question – Peter Wood Mar 25 '21 at 20:06

1 Answers1

1

If you're allowed to use itertools then 1st solution below:

Try it online!

import itertools
print(list(itertools.product(range(2), range(3), range(4))))

Output:

[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 2, 0), (0, 2, 1), (0, 2, 2), (0, 2, 3), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 0, 3), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 0), (1, 2, 1), (1, 2, 2), (1, 2, 3)]

Second solution without using any modules:

Try it online!

def f(*its):
    if len(its) == 0:
        yield ()
    else:
        for e in its[0]:
            for tail in f(*its[1:]):
                yield (e,) + tail

print(list(f(range(2), range(3), range(4))))

Output:

[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 2, 0), (0, 2, 1), (0, 2, 2), (0, 2, 3), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 0, 3), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 0), (1, 2, 1), (1, 2, 2), (1, 2, 3)]
Arty
  • 14,883
  • 6
  • 36
  • 69