2 ^ n комбинаций Itertools с расширенной фильтрацией

Я знаю, что могу использовать itertools для откачки комбинаций и определить размер группы комбинаций, например, так:

import itertools
print list(itertools.combinations(['V','M','T','O','Q','K','D','R'], 4))

Вывод этого будет похож на список кортежей, каждый из которых имеет длину 4 в этом случае.

Отсюда я хотел бы применить 2 параметра: 1) исключить любые комбинации /кортежи, содержащие определенные пары - например, V и M, или Q и K. 2) заставить каждый кортеж содержать только 1 экземпляр письма. Я считаю, что itertools уже делает # 2.

Должны остаться только те группы кортежей, которые не содержат ни одной из этих заранее определенных «ложных» пар. Поэтому, если я исключу группу, которая содержит V и M, группа ('V','M','Q','D') будет недействительной, но ('V','R','Q','D') будет действительным.

Какой лучший способ для меня это сделать?

7 голосов | спросил DNburtonguster 25 MaramFri, 25 Mar 2016 02:26:24 +03002016-03-25T02:26:24+03:0002 2016, 02:26:24

3 ответа


0

вы можете определить функцию проверки и фильтровать ее

>>> import itertools
>>> def is_valid(data):
        if 'V' in data and 'M' in data:
            return False
        if 'Q' in data and 'K' in data:
            return False
        return True

>>> filter(is_valid,itertools.combinations('VMTOQKDR', 4))
[('V', 'T', 'O', 'Q'), ('V', 'T', 'O', 'K'), ('V', 'T', 'O', 'D'), ('V', 'T', 'O', 'R'), ('V', 'T', 'Q', 'D'), ('V', 'T', 'Q', 'R'), ('V', 'T', 'K', 'D'), ('V', 'T', 'K', 'R'), ('V', 'T', 'D', 'R'), ('V', 'O', 'Q', 'D'), ('V', 'O', 'Q', 'R'), ('V', 'O', 'K', 'D'), ('V', 'O', 'K', 'R'), ('V', 'O', 'D', 'R'), ('V', 'Q', 'D', 'R'), ('V', 'K', 'D', 'R'), ('M', 'T', 'O', 'Q'), ('M', 'T', 'O', 'K'), ('M', 'T', 'O', 'D'), ('M', 'T', 'O', 'R'), ('M', 'T', 'Q', 'D'), ('M', 'T', 'Q', 'R'), ('M', 'T', 'K', 'D'), ('M', 'T', 'K', 'R'), ('M', 'T', 'D', 'R'), ('M', 'O', 'Q', 'D'), ('M', 'O', 'Q', 'R'), ('M', 'O', 'K', 'D'), ('M', 'O', 'K', 'R'), ('M', 'O', 'D', 'R'), ('M', 'Q', 'D', 'R'), ('M', 'K', 'D', 'R'), ('T', 'O', 'Q', 'D'), ('T', 'O', 'Q', 'R'), ('T', 'O', 'K', 'D'), ('T', 'O', 'K', 'R'), ('T', 'O', 'D', 'R'), ('T', 'Q', 'D', 'R'), ('T', 'K', 'D', 'R'), ('O', 'Q', 'D', 'R'), ('O', 'K', 'D', 'R')]
>>> 

ИЗМЕНИТЬ

Чтобы сделать его еще более гибким, вы можете создать функцию, которая выполняет функции проверки, и смешать ее с идеей @PadraicCunningham об использовании set

>>> import itertools
>>> def make_validator(*checks):
        checker=[set(x) for x in checks]
        def validator(data):
            return not any( st.issubset(data) for st in checker)
        return validator

>>> is_valid = make_validator("VM","QK")
>>> filter(is_valid, itertools.combinations('VMTOQKDR', 4))
[('V', 'T', 'O', 'Q'), ('V', 'T', 'O', 'K'), ('V', 'T', 'O', 'D'), ('V', 'T', 'O', 'R'), ('V', 'T', 'Q', 'D'), ('V', 'T', 'Q', 'R'), ('V', 'T', 'K', 'D'), ('V', 'T', 'K', 'R'), ('V', 'T', 'D', 'R'), ('V', 'O', 'Q', 'D'), ('V', 'O', 'Q', 'R'), ('V', 'O', 'K', 'D'), ('V', 'O', 'K', 'R'), ('V', 'O', 'D', 'R'), ('V', 'Q', 'D', 'R'), ('V', 'K', 'D', 'R'), ('M', 'T', 'O', 'Q'), ('M', 'T', 'O', 'K'), ('M', 'T', 'O', 'D'), ('M', 'T', 'O', 'R'), ('M', 'T', 'Q', 'D'), ('M', 'T', 'Q', 'R'), ('M', 'T', 'K', 'D'), ('M', 'T', 'K', 'R'), ('M', 'T', 'D', 'R'), ('M', 'O', 'Q', 'D'), ('M', 'O', 'Q', 'R'), ('M', 'O', 'K', 'D'), ('M', 'O', 'K', 'R'), ('M', 'O', 'D', 'R'), ('M', 'Q', 'D', 'R'), ('M', 'K', 'D', 'R'), ('T', 'O', 'Q', 'D'), ('T', 'O', 'Q', 'R'), ('T', 'O', 'K', 'D'), ('T', 'O', 'K', 'R'), ('T', 'O', 'D', 'R'), ('T', 'Q', 'D', 'R'), ('T', 'K', 'D', 'R'), ('O', 'Q', 'D', 'R'), ('O', 'K', 'D', 'R')]
>>> filter(make_validator("VM","QK",'MT',"DR"), itertools.combinations('VMTOQKDR', 4))
[('V', 'T', 'O', 'Q'), ('V', 'T', 'O', 'K'), ('V', 'T', 'O', 'D'), ('V', 'T', 'O', 'R'), ('V', 'T', 'Q', 'D'), ('V', 'T', 'Q', 'R'), ('V', 'T', 'K', 'D'), ('V', 'T', 'K', 'R'), ('V', 'O', 'Q', 'D'), ('V', 'O', 'Q', 'R'), ('V', 'O', 'K', 'D'), ('V', 'O', 'K', 'R'), ('M', 'O', 'Q', 'D'), ('M', 'O', 'Q', 'R'), ('M', 'O', 'K', 'D'), ('M', 'O', 'K', 'R'), ('T', 'O', 'Q', 'D'), ('T', 'O', 'Q', 'R'), ('T', 'O', 'K', 'D'), ('T', 'O', 'K', 'R')]
>>> 

make_validator принимает в качестве аргументов любое количество нежелательных комбинаций исключений и создает функцию, которая выполняет проверку и верни это; Вы можете сохранить результат в переменной или использовать его напрямую

ответил Copperfield 25 MaramFri, 25 Mar 2016 02:38:42 +03002016-03-25T02:38:42+03:0002 2016, 02:38:42
0

Я бы отфильтровал с набором:

import itertools
c = itertools.combinations(['V','M','T','O','Q','K','D','R'], 4)

st = {"V","M"}

print([co for co in c if not st.issubset(co)])

Если вы хотите отфильтровать по двум:

st1 = {"V","M"}
st2 = {"Q","K"}

print([co for co in c if not st1.issubset(co) and not st2.issubset(co)])

Если у вас их больше двух, было бы лучше использовать any:

sts = [{"V","M"},{"V","R"},{"T","O"}]

print([co for co in c if not any(st.issubset(co) for st in sts)])

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

ответил Padraic Cunningham 25 MaramFri, 25 Mar 2016 02:36:50 +03002016-03-25T02:36:50+03:0002 2016, 02:36:50
0

Вы можете использовать понимание списка с условием if:

>>> [x for x in itertools.combinations('VMTOQKDR', 4) 
       if not (('V' in x and 'M' in x) or ('Q' in x and 'K' in x))]
[('V', 'T', 'O', 'Q'),
 ('V', 'T', 'O', 'K'),
 ... 37 more ...
 ('O', 'Q', 'D', 'R'),
 ('O', 'K', 'D', 'R')]

Заметьте, однако, что это все равно будет проходить через все комбинации и просто «выбрасывать» недействительные. Например, если первые два элемента ('V','M'), он продолжит генерировать `('V', 'M', 'O', 'R и выбросить, и так далее. Для количества комбинаций, сгенерированных в этом случае, это не проблема. Для более крупных комбинаций вы можете выбросить недопустимые частичные результаты ранее, используя собственный рекурсивный алгоритм.

ответил tobias_k 25 MaramFri, 25 Mar 2016 02:38:30 +03002016-03-25T02:38:30+03:0002 2016, 02:38:30

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132