比方说,我有一个单词“ stack”,每个字母都有一个数字,该数字将定义字母必须重复的次数。在JSON文件中,我将具有以下内容:
{
"s": 4,
"t": 3,
"a": 2,
"c": 5,
"k": 2
}
由此,我想生成所有可能组合的完整树,即:
Depth 1: stack
Depth 2: stack, sstack, ssstack, sssstack
Depth 3: stack, sttack, stttack, sstack, ssttack, sstttack,ssstack, sssttack, ssstttack, sssstack, ssssttack, sssstttack
Depth 4: ... with 'a'
Depth 5: ... with 'c'
Depth 6: ... with 'k'
这将提供4 * 3 * 2 * 5 * 2 = 240种可能性。另外,我有几天前在这里问过的人提供的这些功能,我对此做了一些修改:
def all_combinations(itr):
lst = list(itr)
for r in range(1, len(lst) + 1):
for perm in itertools.combinations(lst, r=r):
yield perm
def all_repeats(n, letters, word):
for rep in all_combinations(letters):
yield ''.join(char * n if char in rep else char for char in word)
哪个给我:
word = 'stack'
for i in range(1,5):
liste.append(''.join(list(all_repeats(i, ['s'], word))))
Output: ['stack', 'sstack', 'ssstack', 'sssstack']
由此,在JSON文件中有一对(字母,数字)的情况下,如何递归调用此函数来创建所有可能性?
答案 0 :(得分:1)
几个版本,首先我们使用一个列表,因为它更易于索引
options = [
("s", 4),
("t", 3),
("a", 2),
("c", 5),
("k", 2),
]
现在我们可以获得长版版本,以帮助了解发生了什么事情
output = ['']
for letter, repeats in options:
tmp = []
for num in range(repeats):
postfix = letter * (num+1)
for cur in output:
tmp.append(cur + postfix)
output = tmp
如果您print(output)
,您将得到期望的结果。我建议在调试器中运行或插入许多print
语句以了解发生的情况
作为第二个版本,我们可以使用itertools
来缩短这一切:
from itertools import product
tmp = [[l*(i+1) for i in range(num)] for l, num in options]
output = [''.join(l) for l in product(*tmp)]
您甚至可以将所有内容放在一起,但是我认为它有点太难以理解
一个递归解决方案也很合适,但我会留给您
答案 1 :(得分:1)
您还可以使用递归:
data = {'s': 4, 't': 3, 'a': 2, 'c': 5, 'k': 2}
def combos(d):
yield ''.join(map(''.join, d))
for i in data:
if any(c[0] == i and len(c) < data[i] for c in d):
yield from combos([c+[i] if c[0] == i and len(c) < data[i] else c for c in d])