4

The following code works, but appears verbose.

def gen(l):
    for x in range(l[0]):
        for y in range(l[1]):
            for z in range(l[2]):
                yield [x, y, z]
l = [1, 2, 3]
print(list(gen(l)))

>>>[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], [0, 1, 2]]

My intention was to cut down on LOC with itertools.product. Here's what I came up with.

from itertools import product
def gen(l):
    for x, y, z in product(map(range, l)):
        yield [x, y, z]
l = [1, 2, 3]
print(list(gen(l)))

ValueError: not enough values to unpack (expected 3, got 1)

Is there a different way to use itertools.product so that there are enough values to unpack?

CannedSpinach
  • 115
  • 11

1 Answers1

8

You need to pass the elements of the map iterator to product separately with *:

for x, y, z in product(*map(range, l))

Incidentally, with another map call, you could save another line, skip the overhead of a Python generator, and do all the work in C:

def gen(l):
    return map(list, product(*map(range, l)))
user2357112
  • 260,549
  • 28
  • 431
  • 505
  • Using the asterisk to separate elements works perfectly, but the second part of your answer returns a TypeError: 'int' object is not iterable. – CannedSpinach Jul 13 '16 at 22:04
  • 2
    @CannedSpinach: That shouldn't happen. I did miss that it returns an iterator of tuples instead of lists (which you can [fix](http://ideone.com/X53U7S) with another `map` call), but even the version with tuples [doesn't raise a TypeError](http://ideone.com/eKMOkj). – user2357112 Jul 13 '16 at 22:11