现在花了相当多的时间试图找到一种方法(我认为)应该是一个相对简单的程序,我已经设法编写了将产生结果的代码(感谢关于这个奇妙的建议)论坛!),但根据我的计算,计算所有可能性需要几年时间,所以我拼命寻找一些帮助,因为我担心我的计算机可能无法看到那天。 :)非常感谢任何输入!
我想要实现的是来自10个唯一条目的列表(例如['A','B','C','D','E','F','G',H' ,'我','J']),获得超过10的字符串长度的所有排列,但要求1个元素(例如'C')应该恰好发生3次,并且在所有可能的位置。< / p>
现在我正在使用:
options = ['A','B','C','D','E','F','G','H','I','J']
def combos(options,n):
if (n <= 0): return
for s in options:
if len(s) <= n: yield s
for t in combos(options,n-len(s)): yield s+t
for x in combos(options,10):
if x.count("C") == 3 and len(x) == 10:
print x
这样,它正在计算所有可能的排列,并选择具有3'Cs'的排列,因此产生大量不必要的排列,这些排列不包含3'Cs',因此为什么它需要的时间超过必要时间。有没有人有任何建议我如何让Python在生成排列时遵守3x'C'限制?
很多,非常感谢提前!答案 0 :(得分:4)
最简单的方法是使用其他字母生成7个元素的排列,然后将三个C插入其中。
答案 1 :(得分:4)
itertools
是你的朋友:
from itertools import chain, imap, permutations, combinations, repeat
others = [o for o in options if o != 'C']
chain.from_iterable(permutations(*chain(repeat('C', 3), x))
for x in combinations(others, 7))
编辑:这会给出排列,而不是组合;如果您希望结果为AAAAAAACCC .. CCCJJJJJJJ
,那么它必须略有不同。这是一个相当有效的产品/过滤解决方案:
from itertools import product
(x for x in product(options, repeat=10) if x.count('C') == 3)
这是使用BrenBarn建议的交错的方法:
from itertools import product
others = [o for o in options if o != 'C']
(r[:i] + ('C',) + r[i:j] + ('C',) + r[j:k] + ('C',) + r[k:]
for r in product(others, repeat=7)
for i in range(8) for j in range(i, 8) for k in range(j, 8))
你需要自己测试,但对我来说,交错方法要快得多。
答案 2 :(得分:1)
BrenBarn建议可以提供:
from itertools import product, combinations
otheroptions = ['A','B', 'D','E','F','G','H','I','J']
c = "C"
l = 10
nc = 3
for t in product(otheroptions, repeat=l-nc):
for p in combinations(range(l), nc):
r = list(t)
for i in p:
r[i:i] = [c]
print "".join(r)