我有这样的数组,每个模式都指定一个组合形状,每个数字代表组合的大小。
[1, 1, 1, 1]
[2, 1, 1]
[3, 1]
[4]
我也有一个像下面这样的char值列表。 len(chars)等于上部数组值的总和。
chars = ['A', 'B', 'C', 'D']
我希望找到符合给定模式的所有字符组合。例如,对于模式1,4C2 * 2C1 * 1C1是组合的数量。
[['A', 'B'], ['C'], ['D']]
[['A', 'B'], ['D'], ['C']]
[['A', 'C'], ['B'], ['D']]
[['A', 'C'], ['D'], ['B']]
[['A', 'D'], ['B'], ['C']]
[['A', 'D'], ['C'], ['B']]
...
但我不知道如何创建这样的组合数组。当然我知道python中的组合有很多有用的功能。但我不知道如何使用它们来创建组合的组合数组。
EDITED
我很抱歉我的解释令人困惑。我举了一个简单的例子。
[1, 1]
[2]
chars = ['A', 'B']
然后,结果应如下所示。所以第一维应该是排列,但第二维应该是组合。
[['A'], ['B']]
[['B'], ['A']]
[['A', 'B']] # NOTE: [['B', 'A']] is same in my problem
答案 0 :(得分:1)
您可以使用递归函数来获取模式中的第一个数字,并从剩余项目中生成该长度的所有组合。然后继续使用剩余的模式&项目和生成的前缀。一旦你将yield
模式中的所有数字一直消耗到调用者的前缀:
from itertools import combinations
pattern = [2, 1, 1]
chars = ['A', 'B', 'C', 'D']
def patterns(shape, items, prefix=None):
if not shape:
yield prefix
return
prefix = prefix or []
for comb in combinations(items, shape[0]):
child_items = items[:]
for char in comb:
child_items.remove(char)
yield from patterns(shape[1:], child_items, prefix + [comb])
for pat in patterns(pattern, chars):
print(pat)
输出:
[('A', 'B'), ('C',), ('D',)]
[('A', 'B'), ('D',), ('C',)]
[('A', 'C'), ('B',), ('D',)]
[('A', 'C'), ('D',), ('B',)]
[('A', 'D'), ('B',), ('C',)]
[('A', 'D'), ('C',), ('B',)]
[('B', 'C'), ('A',), ('D',)]
[('B', 'C'), ('D',), ('A',)]
[('B', 'D'), ('A',), ('C',)]
[('B', 'D'), ('C',), ('A',)]
[('C', 'D'), ('A',), ('B',)]
[('C', 'D'), ('B',), ('A',)]
请注意,上述内容仅适用于Python 3,因为它使用的是yield from
。