Green Cell Green Cell - 17 days ago 7
Python Question

Python: Replacing multiple words with a random choice

I have a phrase with some special marked words which I want to replace. These words match a key in a dictionary, which has a list of words that I want to randomly choose to replace with.

I'm wondering if there's a better way to go about doing this, or is what I have seem like a valid approach? I have a feeling there may be a smarter way with

lambda
but I'm not sure.

Hopefully the code explains for itself!

import random

words = {"fruit":["apples", "bananas", "oranges"],
"veggies":["broccoli", "corn", "cucumbers"]}

txt = "I'm not in a mood for [veggies], I rather have [fruit], and [fruit]."

for key in words:
target_word = "[{0}]".format(key)

while target_word in txt:
txt = txt.replace(target_word, random.choice(words[key]), 1)


Running it a few times will randomly output:


I'm not in a mood for corn, I rather have bananas, and apples.

I'm not in a mood for broccoli, I rather have oranges, and bananas.

I'm not in a mood for cucumbers, I rather have apples, and oranges.

..and so on..


I should mention that there could be any number of keys in
words
, and any number of marked words in the text.

Answer

re.sub also accepts a callable as repl argument:

In [19]: import random, re
    ...: 
    ...: words = {"fruit":["apples", "bananas", "oranges"], 
    ...:          "veggies":["broccoli", "corn", "cucumbers"]}
    ...: 
    ...: txt = "I'm not in a mood for [veggies], I rather have [fruit], and [fruit]."
    ...: 

In [20]: regex = re.compile(r'\[({})\]'.format('|'.join(words)))

In [21]: regex.pattern
Out[21]: '\\[(fruit|veggies)\\]'

In [22]: regex.sub(lambda match: random.choice(words[match.group(1)]), txt)
Out[22]: "I'm not in a mood for broccoli, I rather have bananas, and apples."

In [23]: regex.sub(lambda match: random.choice(words[match.group(1)]), txt)
Out[23]: "I'm not in a mood for corn, I rather have oranges, and oranges."

I think that it's against Python Zen though.

Comments