2017-01-17 7 views
2

я следующее:Использование Itertools для создания списка комбинации элементов из нескольких списков

a = [i/100 for i in range(5,105,5)] 
a.append(0) 
b = [i/100 for i in range(5,105,5)] 
b.append(0) 
c = [i/100 for i in range(5,105,5)] 
c.append(0) 
d = [i/100 for i in range(5,105,5)] 
d.append(0) 
e = [i/100 for i in range(5,105,5)] 
e.append(0) 

combs = itertools.product(a,b,c,d,e) 

«гребенки» даст мне все возможные комбинации а, Ь, с, d и е. Тем не менее, мне было интересно, могу ли я объединить их так, чтобы они составляли до 1.

Спасибо.

+5

[гребень для гребенки в гребнях, если сумма (гребенка) = = 1] – user3684792

+1

@ user3684792: хотя это работает, было бы довольно неэффективно, не так ли? –

+0

'list (filter (lambda x: sum (x) == 1, itertools.product (a, a, a, a, a)))' –

ответ

1

Насколько я знаю, нет встроенного способа в для этого. Вы можете, очевидно, отфильтровать результат, но это было бы довольно неэффективно: ожидается лишь небольшое количество комбинаций, чтобы добавить до sum.

Учитывая все поданные значения положительны (ноль приемлемо), однако, вы можете использовать эту ленивую функцию:

def product_sum(sum,*args): 
    return product_sum_intern(sum,0,0,[],*args) 

def product_sum_intern(sum,cur_sum,idx,cur,*args): 
    if idx >= len(args): 
     if sum == cur_sum: 
      yield tuple(cur) 
    elif cur_sum <= sum: 
     for x in args[idx]: 
      cur.append(x) 
      for e in product_sum_intern(sum,cur_sum+x,idx+1,cur,*args): 
       yield e 
      cur.pop() 

Например:

>>> list(product_sum(15,[1,12],[1,4,7],[0,3,6,7],[0,1])) 
[(1, 7, 6, 1), (1, 7, 7, 0)] 

этот алгоритм дает на отрасли, как вскоре выяснилось, что это уже превысило сумму. Существует более сложный алгоритм, который также отказывается от ветвей, если нет возможности получить доступ к сумме.

+1

Очень эффективный и совершенный! Спасибо @ Виллем Ван Онсем. – DPdl

+0

@DPdl: добро пожаловать :). –

0

Чтобы получить список всех таких результатов:

combs = [comb for comb in combs if sum(comb) ==1] 

Или, если вы можете использовать генератор этих данных:

combs = (comb for comb in combs if sum(comb) ==1) 
+3

Я верю @ user3684792 23 дал этот ответ – pylang