【问题标题】:What's the best way to produce combinations in order?按顺序生成组合的最佳方法是什么?
【发布时间】:2016-05-02 14:55:22
【问题描述】:
l = ['A', 'B', 'C', 'D']

我想按顺序排列所有组合。所以输出应该是这样的,

['ABCD', 'ABC', 'AB', 'A', 'BCD', 'BC', 'B', 'CD', 'C', 'D']

我试过的是..

>>> o = set()
>>> for i, j in enumerate(l):
    o.add(''.join(l[:i]))
    o.add(''.join(l[i:]))


>>> 
>>> o
set(['', 'ABCD', 'AB', 'D', 'BCD', 'CD', 'ABC', 'A'])

但它错过了BC。还尝试了itertools.combinations,但它提供了所有可能的组合,而与顺序无关。

【问题讨论】:

  • 准确地说,你错过了'B', 'C''BC'
  • @Antonio ??我加了。
  • 您的问题类似于this,但输出立即排序?
  • 标准方式是递归。您采用长度为 1 的组合并将其他字符放在两侧。然后你把这些字符放在它们之间。
  • @Antonio 我在他们的回答中看到了(1, 3)

标签: python


【解决方案1】:

如果您只查找列表的连续子段,只需迭代开始和结束位置的可能组合并生成一致的切片。由于end 位置取决于start,我认为没有办法使用itertools 函数之一来做到这一点。

def comb_in_order(lst):
    for start in range(0, len(lst)):
        for end in range(len(lst), start, -1):
            yield lst[start:end]

例子:

>>> [''.join(c) for c in comb_in_order(['A', 'B', 'C', 'D'])]
['ABCD', 'ABC', 'AB', 'A', 'BCD', 'BC', 'B', 'CD', 'C', 'D']

可以使用带有附加条件的itertools.product,但这样您将遍历许多无论如何都会被过滤掉的组合,并且结果的顺序略有不同:

>>> [''.join(lst[s:e+1]) for s,e in itertools.product(range(len(lst)), repeat=2) if s <= e]
['A', 'AB', 'ABC', 'ABCD', 'B', 'BC', 'BCD', 'C', 'CD', 'D']

【讨论】:

    【解决方案2】:

    我想指出,每个组合都映射到 0 到 2^n-1 之间的二进制名称,其中n 是原始字符串的长度(如果您想忽略空组合,则从 1 开始。ABCD是 1111,ABC 是 1110,依此类推。

    生成这些值并进行映射。

    另一种看待同一事物的方式,ABCD 的所有组合都是 BCD 的所有组合以及所有带有 A 前缀的组合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 2020-10-05
      相关资源
      最近更新 更多