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

У меня есть список столбцов с данными:

L=[AA ,  AS  ,  AD  , BB  , BC  , CD ,  CF,CG ]

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

Однако у меня может быть только одно имя, начинающееся с A в каждой комбинации, НО у меня может быть несколько имен, начинающихся с C или ни одного.

Что касается B, у меня должно быть как минимум 1 B, но может быть больше

Поэтому мне нужны все комбинации

A=[AA,AS,AD] #only one of these
B=[BB,BC]  #at least one of these
all_others=[CD,CF,CG]  #All, 1, 2 or none of these

Пока у меня есть этот код;

from itertools import product

for choices in product(['AA','AS','AD',None],['BB', 'BC', None], ['CD','CF', None],):
    print(' '.join(column for column in choices if column))

Это работает, однако, оно допускает только одно значение, начинающееся с C, но я хочу product все комбинации C. Может кто-нибудь увидеть хорошее редактирование, которое я могу сделать?

Подводя итог;Мне нужны все комбинации имен в списке.С одним правилом, вы не можете иметь более 1 переменной, начиная с A, и более одной переменной, начиная с B

Ответы [ 3 ]

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

Попробуйте это вместо вашей петли for:

for choices in itertools.product(['AA','AS','AD',None],['BB', 'BC', None],[' '.join(k) for j in list(itertools.combinations(['CD','CF'],i) for i in range(3)) for k in j]):
    # do what you need

вывод для выбора с использованием print(' '.join(column for column in choices if column)):

AA BB
AA BB CD
AA BB CF
AA BB CD CF
AA BC
AA BC CD
AA BC CF
AA BC CD CF
AA
AA CD
AA CF
AA CD CF
AS BB
AS BB CD
AS BB CF
AS BB CD CF
AS BC
AS BC CD
AS BC CF
AS BC CD CF
AS
AS CD
AS CF
AS CD CF
AD BB
AD BB CD
AD BB CF
AD BB CD CF
AD BC
AD BC CD
AD BC CF
AD BC CD CF
AD
AD CD
AD CF
AD CD CF
BB
BB CD
BB CF
BB CD CF
BC
BC CD
BC CF
BC CD CF

CD
CF
CD CF

Я рекомендую заменить None на '' или удалите их.

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

Вот более надежный / общий способ сделать то, что вы хотите.Я начинаю с определения вспомогательной функции:

from itertools import combinations, chain, product

def subsets_of_length(s, lengths):
    return chain.from_iterable(combinations(s,l) for l in lengths)

Она производит следующий вывод:

>>>> list(subsets_of_length(['a','b','c'], range(2,4)))
[('a', 'b'), ('a', 'c'), ('b', 'c'), ('a', 'b', 'c')]

>>>> list(subsets_of_length(['d','e'], range(0,2)))
[(), ('d',), ('e',)]

Теперь мы хотим объединить два или более подмножества следующим образом

>>>> for choices in product(
         subsets_of_length(['a','b','c'], range(2,4)),
         subsets_of_length(['d','e'], range(0,2)),
     ):
         print(' '.join(str(subset) for subset in choices))

('a', 'b') ()
('a', 'b') ('d',)
('a', 'b') ('e',)
('a', 'c') ()
('a', 'c') ('d',)
('a', 'c') ('e',)
('b', 'c') ()
('b', 'c') ('d',)
('b', 'c') ('e',)
('a', 'b', 'c') ()
('a', 'b', 'c') ('d',)
('a', 'b', 'c') ('e',)

Но мы хотим связать эти кортежи вместе.Таким образом, мы должны сделать

>>>> for choices in map(chain.from_iterable,product(
         subsets_of_length(['a','b','c'], range(2,4)),
         subsets_of_length(['d','e'], range(0,2)),
     )):
         print(' '.join(column for column in choices if column))

a b
a b d
a b e
a c
a c d
a c e
b c
b c d
b c e
a b c
a b c d
a b c e

Код для случая вашего отредактированного вопроса будет:

for choices in map(chain.from_iterable,product(
    subsets_of_length(['AA','AS','AD'], [1]),       #only one of these
    subsets_of_length(['BB','BC'], [1,2]),          #at least one of these
    subsets_of_length(['CD','CF','CG'], [0,1,2,3]), #All, 1, 2 or none of these
)):
    print(' '.join(column for column in choices if column))
0 голосов
/ 10 декабря 2018

Конечно, чтобы выразить

all_others=[CD,CF,CG]  #All, 1, 2 or none of these

, разбейте его на

all_others=[CD]  #one or none of these
all_others=[CF]  #one or none of these
all_others=[CG]  #one or none of these

Тогда ваш код станет

from itertools import product

for choices in product(['AA','AS','AD',None],['BB', 'BC', None], ['CD', None], ['CF', None], ['CG', None],):
    print(' '.join(column for column in choices if column))

Это обрабатывает этот конкретный пример.Однако, если вместо этого у вас есть несколько элементов, начинающихся с C, они могут обрабатываться более систематически следующим образом:

from itertools import product

for choices in product(['AA','AS','AD',None],['BB', 'BC', None], *product(['CD', 'CF', 'CG'], [None]),):
    print(' '.join(column for column in choices if column))

Чтобы объяснить, что происходит, взяв произведение ['CD', 'CF', 'CG'] с [None], вы получите итераторсодержащий

('CD', None), ('CF', None), ('CG', None)

Именно эти аргументы мы хотим передать product Оператор * преобразует элементы внутри итератора в аргументы функции.Таким образом, приведенные выше два фрагмента кода эквивалентны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...