简体   繁体   中英

Python: create all derivatives of string by replacing its symbols

I've got some dict like that

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

My goal is to create a list of all possible derivatives from initial word by replacing its elements like that:

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

Order of words in rez is not important.

I feel that there should be some easy way with itertools , but I can't see it. Any nice and beautiful solution would be very welcome.

Sure, itertools is always the answer for these kind of problems. There may be better alternatives but the first that comes to my mind is using itertools.product :

from itertools import product

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

Output

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

Here is one approach. Since you want to allow non-replacement (eg, leaving "a" as "a"), it is better to include the original character in the list of replacement values, so that the dict has, eg, 'a': ['a', '1', '+', '='] . This can be done with:

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

Then:

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)

The result:

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

Just for fun. No import , no def , no indentation.

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"])

Result:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM