Как я могу динамически получить комбинацию / перестановку групп в Python? - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть 3 группы

[1,2] [4,5] [a,b]

Мне нужны такие комбинации / комбинации

1  4  a
1  5  a
1  4  b
1  5  b
2  4  a    
2  5  a
2  4  b
2  5  b
12 4  a
12 5  a
12 4  b
12 5  b
12 4  ab
12 5  ab
1  45 a
2  45 a
1  45 b
2  45 b
1  45 ab
2  45 ab
1  4  ab
2  5  ab
12 45 ab

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

Я до сих пор получил это.

from itertools import *

bag1 = [1, 2]
bag2 = [4, 5]
bag3  = ['a', 'b']

bags = []

bags.append(bag1)
bags.append(bag2)
bags.append(bag3)

comb = list(product(*bags))

Ответы [ 3 ]

0 голосов
/ 06 декабря 2018

Учитывая ваш код, вам нужно использовать декартово произведение (произведение) на всех возможных комбинациях ваших начальных «сумок»:

from itertools import product, combinations

def comb_bag( bag):
    new_bag = []
    for n in range( 1, 1+len(bag)):
        new_bag += list( combinations(bag, n))

    return new_bag

bag1 = [1, 2]
bag2 = [4, 5]
bag3  = ['a', 'b']

bags = []

new_bag1 = comb_bag( bag1)
new_bag2 = comb_bag( bag2)
new_bag3 = comb_bag( bag3)

bags.append(new_bag1)
bags.append(new_bag2)
bags.append(new_bag3)

comb = list(product(*bags))

for e in comb:
    print( e)
0 голосов
/ 06 декабря 2018

Я думаю, что вы хотите, чтобы получить комбинации каждой группы в отдельности, а затем получить продукт групп.Оттуда вы можете выполнить некоторую обработку, если хотите строки или что-то еще.

from itertools import combinations, product

groups = [[1, 2], [3, 4], ['a', 'b']]

# Note you want groups of all sizes:
sub_combs = []
for g in groups:
    group_combs = []
    for r in range(len(g)):
        combs = combinations(g, r+1) #Combinations of all (nonempty) sizes
        group_combs += list(combs)
    sub_combs.append(group_combs)
final_combs = list(product(*sub_combs))

final_combs

[((1,), (3,), ('a',)),
 ((1,), (3,), ('b',)),
 ((1,), (3,), ('a', 'b')),
 ((1,), (4,), ('a',)),
 ((1,), (4,), ('b',)),
 ((1,), (4,), ('a', 'b')),
 ((1,), (3, 4), ('a',)),
 ((1,), (3, 4), ('b',)),
 ((1,), (3, 4), ('a', 'b')),
 ((2,), (3,), ('a',)),
 ((2,), (3,), ('b',)),
 ((2,), (3,), ('a', 'b')),
 ((2,), (4,), ('a',)),
 ((2,), (4,), ('b',)),
 ((2,), (4,), ('a', 'b')),
 ((2,), (3, 4), ('a',)),
 ((2,), (3, 4), ('b',)),
 ((2,), (3, 4), ('a', 'b')),
 ((1, 2), (3,), ('a',)),
 ((1, 2), (3,), ('b',)),
 ((1, 2), (3,), ('a', 'b')),
 ((1, 2), (4,), ('a',)),
 ((1, 2), (4,), ('b',)),
 ((1, 2), (4,), ('a', 'b')),
 ((1, 2), (3, 4), ('a',)),
 ((1, 2), (3, 4), ('b',)),
 ((1, 2), (3, 4), ('a', 'b'))]
0 голосов
/ 06 декабря 2018

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

from itertools import *


def subsets(xs):
    for k in range(1, len(xs) + 1):
        yield from combinations(xs, k)


lst = [[1, 2], [4, 5], ["a", "b"]]

result = list(product(*map(subsets, lst)))

# first few values
# [((1,), (4,), ('a',)),
# ((1,), (4,), ('b',)),
# ((1,), (4,), ('a', 'b')),
# ((1,), (5,), ('a',)),
# ((1,), (5,), ('b',)),

# pretty print
for line in result[:5]:
    line = " ".join("".join(map(str, tok)) for tok in line)
    print(line)


# 1 4 a
# 1 4 b
# 1 4 ab
# 1 5 a
# 1 5 b
...