Python: how to get this elegantly?
Question: I'm new to Python and I wrote a function:

    
    
    def f(x, y, z):
        ret = []
        for i in range(x):
            for j in range(y):
                for k in range(z):
                    ret.append((i, j, k))
        return ret
    
    
    print f(2, 3, 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)]
    

But I'm not satisfied with that because I think there must be a shorter
implementation.

So could any one give me some hint about that?


Answer: You can use
[`itertools.product`](https://docs.python.org/3/library/itertools.html#itertools.product)
because that is essentially what you are after, the [Cartesian
product](https://en.wikipedia.org/wiki/Cartesian_product)

    
    
    >>> from itertools import product
    >>> list(product(range(2), range(3), range(4)))
    [(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)]
    

So replacing your existing function you could do

    
    
    def f(x, y, z):
        return list(product(range(x), range(y), range(z)))
    

To remove the number of times you have to type out `range`, you could accept a
single list argument then use a generator expression such as

    
    
    def f(l):
        return list(product(*(range(i) for i in l)))
    

So then you could call it as

    
    
    >>> f([2,3,4])
    [(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)]
    

