2016-07-13 3 views
2

Следующий код работает, но отображается подробный.Использование itertools.product вместо двойного вложенного цикла цикла в Python 3

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]] 

Мое намерение состояло в том, чтобы сократить LOC с помощью itertools.product. Вот что я придумал.

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) 

Есть ли другой способ использовать itertools.product, чтобы было достаточно значений для распаковки?

ответ

5

Вам необходимо пройти элементы map итератора для product отдельно *:

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

Кстати, с другой map вызова, вы можете сэкономить еще одну строку, пропустить нагрузку генератора Python и сделать все работы в C:

def gen(l): 
    return map(list, product(*map(range, l))) 
+0

Использование звездочки для разделения элементов отлично работает, но вторая часть вашего ответа возвращает объект TypeError: 'int' не является итерируемым. – CannedSpinach

+1

@CannedSpinach: Этого не должно быть. Я пропустил, что он возвращает итератор кортежей вместо списков (который вы можете [исправить] (http://ideone.com/X53U7S) с другим вызовом 'map'), но даже версия с кортежами [не поднимает a TypeError] (http://ideone.com/eKMOkj). – user2357112

Смежные вопросы