字符串中所有可能的替换

时间:2019-06-01 21:57:07

标签: python

假设给我们一个字符串string='..pp.f.'

我们想找到任何数量的'。'字符串的所有可能的变体。被字母“ a”代替。

为了澄清,这就是我们想要的输出:

['a.pp.f.', '.app.f.', ... , '.appaf.',...,'aappafa'] 

使用(主要是)python内置函数实现此目的的最佳方法是什么?

4 个答案:

答案 0 :(得分:0)

这仅使用内置函数查找所有替换项:

def all_replacements(string):
    # base case - easy if there's only one character
    if len(string) == 1:
        if string == '.':
            return ['.', 'a']
        else:
            return [string]

    # if there are multiple characters, break it down into easier problems
    else:
        variations_from_substring = all_replacements(string[1:])
        variations_from_char = all_replacements(string[0])
        return [character + substring for character in variations_from_char for substring in variations_from_substring]


print(all_replacements('..pp.f.'))

打印内容如下:

['..pp.f.', '..pp.fa', '..ppaf.', '..ppafa', '.app.f.', '.app.fa', '.appaf.', '.appafa', 'a.pp.f.', 'a.pp.fa', 'a.ppaf.', 'a.ppafa', 'aapp.f.', 'aapp.fa', 'aappaf.', 'aappafa']

答案 1 :(得分:0)

您可以使用itertools来帮助自己。特别是itertools recipes中的函数powerset允许找到所有要替换的点的组合。

代码

from itertools import chain, combinations

def powerset(iterable):
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

def replacements(s, char):
    dots = [i for i  in range(len(s)) if s[i] == '.']

    for indices in powerset(dots):
        yield ''.join([char if i in indices else s[i] for i in range(len(s))])

print(*replacements('..pp.f.', 'a'), sep='\n')

输出

..pp.f.
a.pp.f.
.app.f.
..ppaf.
..pp.fa
aapp.f.
a.ppaf.
a.pp.fa
.appaf.
.app.fa
..ppafa
aappaf.
aapp.fa
a.ppafa
.appafa
aappafa

答案 2 :(得分:0)

这里的解决方案比其他解决方案更长。它使用itertools的“积”来获取点和字母“ a”的积。

from itertools import product

s = '..pp.f.'
count = s.count('.')
result = []

for tup in product(['.','a'], repeat=count):
    idx = 0
    j = 0

    while '.' in s[idx:]:
        idx = s.index('.', idx)
        string = s[:idx] + s[idx].replace('.', tup[j]) + s[idx+1:]
        idx += 1
        j += 1

    result.append(string)

print(*result, sep='\n')

产品外观如下:

('.', '.', '.', '.')
('.', '.', '.', 'a')
('.', '.', 'a', '.')
('.', '.', 'a', 'a')
('.', 'a', '.', '.')
('.', 'a', '.', 'a')
('.', 'a', 'a', '.')
...

输出为:

..pp.f.
..pp.fa
..ppaf.
..ppafa
.app.f.
.app.fa
.appaf.
.appafa
a.pp.f.
a.pp.fa
a.ppaf.
a.ppafa
aapp.f.
aapp.fa
aappaf.
aappafa

答案 3 :(得分:0)

您可以尝试以下方法:

from itertools import combinations

s = '..pp.f.'
dot_inds = [ind for ind, c in enumerate(s) if c == '.']

ways = [s]
for choose in range(1, len(dot_inds) + 1):
    for comb in combinations(dot_inds, choose):
        lst_s = list(s)
        for dot_ind in comb:
            lst_s[dot_ind] = 'a'
        ways.append(''.join(lst_s))

print(ways)

这将给出:

['..pp.f.', 'a.pp.f.', '.app.f.', '..ppaf.', '..pp.fa', 'aapp.f.', 'a.ppaf.', 'a.pp.fa', '.appaf.', '.app.fa', '..ppafa', 'aappaf.', 'aapp.fa', 'a.ppafa', '.appafa', 'aappafa']