我知道我可以使用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')
将有效。
对我来说,最好的方法是什么?
答案 0 :(得分:3)
您可以定义验证功能并使用
进行过滤>>> 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
将您不想要的任意数量的排除组合作为参数,并创建一个执行检查并返回它的函数;您可以将结果保存在变量中或直接使用
答案 1 :(得分:1)
我会过滤一套:
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)])
禁止你自己组合逻辑,你不能避免创建所有组合和过滤,即使你自己滚动你在纯python中做它可能会慢一点你有一个大数据集
答案 2 :(得分: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')并扔掉它,依此类推。对于在这种情况下生成的组合数量,这不是问题。对于较大的组合,您可能希望使用自定义递归算法提前丢弃无效的部分结果。