Python:通过替换符号来创建字符串的所有派生词

时间:2014-09-16 19:36:18

标签: python string itertools

我有一些类似的词典

d = {'a' : ['1', '+', '='], 'b' : ['2'], c : ['3']}

我的目标是通过替换其中的元素来创建一个包含所有可能衍生物的列表:

word = 'abcde'
rez = ['abcde', 
       '1bcde', '+bcde', '=bcde', 
       'a2cde', '12cde', '+2cde', '=2cde', 
       'ab3de', '1b3de', '+b3de', '=b3de', 'a23de', '123de', '+23de', '=23de']

rez中的单词顺序并不重要。

我觉得itertools应该有一些简单的方法,但我看不到它。 任何美好而美丽的解决方案都会非常受欢迎。

3 个答案:

答案 0 :(得分:5)

当然,itertools始终是这类问题的答案。可能有更好的选择,但我首先想到的是使用itertools.product

from itertools import product

[''.join(chars) for chars in product(*[[x] + d.get(x, []) for x in word])]

输出

['abcde', 'ab3de', 'a2cde', 'a23de', '1bcde', '1b3de', '12cde', '123de',
 '+bcde', '+b3de', '+2cde', '+23de', '=bcde', '=b3de', '=2cde', '=23de']

答案 1 :(得分:4)

这是一种方法。由于您希望允许非替换(例如,离开" a" as" a"),最好将原始字符包含在替换值列表中,以便dict有,例如,'a': ['a', '1', '+', '=']。这可以通过以下方式完成:

for k in d:
    d[k].append(k)

然后:

subs = [[(k, v) for v in vs] for k, vs in d.iteritems()]  
rez = []
for comb in itertools.product(*subs):
    baseword = word
    for before, after in comb:
        baseword = baseword.replace(before, after)
    rez.append(baseword)

结果:

['123de', '1b3de', '12cde', '1bcde', '+23de', '+b3de', '+2cde', '+bcde', '=23de', '=b3de', '=2cde', '=bcde', 'a23de', 'ab3de', 'a2cde', 'abcde']

答案 2 :(得分:1)

只是为了好玩。没有import,没有def,没有缩进。

d = {'a' : ['1', '+', '='], 'b' : ['2'], 'c' : ['3']}
for key in d: d[key].append(key)
print reduce(lambda items, f: sum(map(f, items), []), [lambda msg, c=c: [msg.replace(c, r) for r in d[c]] for c in d.keys()], ["abcde"])

结果:

[
    '123de', '1b3de', '12cde', '1bcde', 
    '+23de', '+b3de', '+2cde', '+bcde', 
    '=23de', '=b3de', '=2cde', '=bcde', 
    'a23de', 'ab3de', 'a2cde', 'abcde'
]