Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate all possible replacements

Given a replacement map like {search: replace, search: replace, ...} and a string, how to generate a list of all possible replacements of that string (first substring replaced, second substring replaced, both replaced etc). Example:

map = {
    'bee': 'BETA',
    'zee': 'ZETA',
    'dee': 'DELTA'
}

source_string = 'bee foo zee bar bee'

desired result = 
[
    'bee foo zee bar bee', 
    'BETA foo zee bar bee', 
    'bee foo ZETA bar bee', 
    'BETA foo ZETA bar bee', 
    'bee foo zee bar BETA', 
    'BETA foo zee bar BETA', 
    'bee foo ZETA bar BETA', 
    'BETA foo ZETA bar BETA'
]

The order is not important.

like image 593
georg Avatar asked May 09 '13 13:05

georg


Video Answer


2 Answers

'bee foo zee bar bee' => ['bee', 'foo', 'zee', 'bar', 'bee']:

from itertools import product

repl = {
    'bee': 'BETA',
    'zee': 'ZETA',
    'dee': 'DELTA'
}
source_string = 'bee foo zee bar bee'
p = product(*((x, repl[x]) if x in repl else (x,) for x in source_string.split()))
for x in p:
    print(x)

Output:

('bee', 'foo', 'zee', 'bar', 'bee')
('bee', 'foo', 'zee', 'bar', 'BETA')
('bee', 'foo', 'ZETA', 'bar', 'bee')
('bee', 'foo', 'ZETA', 'bar', 'BETA')
('BETA', 'foo', 'zee', 'bar', 'bee')
('BETA', 'foo', 'zee', 'bar', 'BETA')
('BETA', 'foo', 'ZETA', 'bar', 'bee')
('BETA', 'foo', 'ZETA', 'bar', 'BETA')
like image 70
kalgasnik Avatar answered Sep 21 '22 23:09

kalgasnik


Itertools.product could help you here. In your example you have binary choice for three words in your string. So

itertools.product((0, 1), repeat=3)

will give you your 8 possible replacements for bee and zee, where 0 means don't replace and 1 means replace with BETA and ZETA respectively.

The following does what you want.

#!python3

import itertools

map = {
    'bee': 'BETA',
    'zee': 'ZETA',
    'dee': 'DELTA'
}

source_string = 'bee foo zee bar bee'

products = []
for word in source_string.split():
    if word in map:
        products.append((word, map[word]))
    else:
        products.append((word, ))

for words in itertools.product(*products):
    print(' '.join(words))
like image 33
Gary Kerr Avatar answered Sep 19 '22 23:09

Gary Kerr