对于递归来说可能现在还太早,但是我为此提出了正确算法的麻烦。
我有一个这样的字符串:abcd
除了我不完全确定它的所有字母。 a
实际上应该是A
,甚至可能是@
。 d
可以是d
,也可以是D
甚至是+
。所以我想出了这个:
possibilities = [['a', 'A', '@'], 'bc', ['d', 'D', '+']]
我想提出一个可能的所有单词的列表:
output = [
'abcd',
'Abcd',
'@bcd',
'abcD',
# etc.
]
此列表的顺序对我来说无关紧要。
我看了itertools
,但是从一眼望去,我找不到适合我的功能,所以我决定实施一个递归解决方案。
def find_possible_strings(possibilities):
res = []
f2(possibilities, '', res)
return res
def f2(possibilities, s, final_result):
for i,elem in enumerate(possibilities):
if type(elem) == str:
s += elem
else:
for e in elem:
f2(possibilities[i+1:], s + e, final_result)
final_result.append(s)
possibilities = [['a', 'A', '@'], 'bc', ['d', 'D', '+']]
print '\n'.join(find_possible_strings(possibilities))
现在,它打印出来:
abcd
abcD
abc+
abc
Abcd
AbcD
Abc+
Abc
@bcd
@bcD
@bc+
@bc
bcd
bcD
bc+
bc
我相信我得到了我想要的所有可能的字符串,但也有一堆不完整的字符串。我认为问题是我没有添加到s
块中的else
,因此我在函数末尾附加的s
不完整。
除非在功能结束时投掷像if len(s) != 4: return
这样的作弊,我该如何修复此功能?
如果另一个更合适,您可以更改输入和输出数据结构。当然,如果事情变得更简单,你可以用库调用替换我的函数。
在此期间我会更多地修补它。
答案 0 :(得分:4)
这不是一个递归形状的问题,所以放下锤子。
您正在生成4个可能性列表的笛卡尔积,每个位置一个。使用itertools.product()
(并为每个位置提供自己的列表),您就完成了:
from itertools import product
possibilities = [['a', 'A', '@'], ['b'], ['c'], ['d', 'D', '+']]
for combo in product(*possibilities):
print(''.join(combo))
演示:
>>> from itertools import product
>>> possibilities = [['a', 'A', '@'], ['b'], ['c'], ['d', 'D', '+']]
>>> for combo in product(*possibilities):
... print(''.join(combo))
...
abcd
abcD
abc+
Abcd
AbcD
Abc+
@bcd
@bcD
@bc+