【问题标题】:Permutation method in Python with some fixed elementsPython中具有一些固定元素的排列方法
【发布时间】:2012-08-22 17:11:14
【问题描述】:

现在花了相当多的时间试图想出一个方法来(我认为)应该是一个相对简单的过程,我已经设法编写了将生成结果的代码(感谢关于这个美妙的建议论坛!),但根据我的计算,计算所有可能性需要几年时间,所以我拼命寻求帮助,因为我担心我的电脑可能活不到那一天。 :) 任何意见将不胜感激!

我想要实现的是来自 10 个唯一条目的列表(例如 ['A','B','C','D','E','F','G',H' ,'I','J']),获取字符串长度为 10 的所有排列,但要求元素中的 1 个(例如 'C')应恰好出现 3 次,并且在所有可能的位置。

我现在正在使用:

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 个“C”的排列,因此会生成大量不包含 3 个“C”的不必要排列,因此它花费的时间比必要的要长。有没有人有任何建议我如何让 Python 在生成排列时遵守 3x 'C' 限制?

提前非常感谢!

【问题讨论】:

    标签: python permutation restrictions


    【解决方案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)
    

    【讨论】:

      【解决方案2】:

      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))
      

      您需要自己测试,但对我来说,interleave 方法要快得多。

      【讨论】:

      • 非常感谢大家的好建议! interleave 方法确实似乎是最快的,现在它已经设法在一夜之间生成列表,让我印象深刻!最终使用了 MatthieuW 的代码,绝对是一种享受,非常感谢!
      【解决方案3】:

      最简单的方法是使用其他字母生成 7 个元素的排列,然后将三个 C 插入其中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-23
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 2017-03-10
        • 1970-01-01
        • 2017-07-05
        相关资源
        最近更新 更多