2016-11-15 5 views
1

Ich habe eine Phrase mit einigen speziellen markierten Wörtern, die ich ersetzen möchte. Diese Wörter entsprechen einem Schlüssel in einem Wörterbuch, das eine Liste von Wörtern enthält, die ich nach dem Zufallsprinzip durch ersetzen möchte.Python: Ersetzen mehrerer Wörter durch eine zufällige Auswahl

Ich frage mich, ob es einen besseren Weg gibt, dies zu tun, oder ist das, was ich habe, ein gültiger Ansatz? Ich habe das Gefühl, dass es einen klügeren Weg mit lambda geben kann, aber ich bin mir nicht sicher.

Hoffentlich erklärt der Code für sich!

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) 

Lauf es ein paar Mal zufällig ausgegeben werden:

Ich bin nicht für Mais in einer Stimmung, ich habe eher Bananen und Äpfel.

Ich bin nicht in der Stimmung für Brokkoli, ich habe eher Orangen und Bananen.

Ich bin nicht in der Stimmung für Gurken, ich habe eher Äpfel und Orangen.

..und so weiter ..

Ich sollte erwähnen, dass es in words und eine beliebige Anzahl von markierten Wörter im Text eine beliebige Anzahl von Tasten sein könnte.

Antwort

2

re.sub akzeptiert auch eine aufrufbar als 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." 

Ich denke, dass es gegen Python Zen ist.

+0

Danke, obwohl ich mag, was du herausgefunden hast, stimme ich etwas mit Python Zen überein. Vielleicht ist es das Beste, einfach bei dem zu bleiben, was ich dann habe. –

+0

@GreenCell Ja, aber re ist schneller. Es lohnt sich, wenn Geschwindigkeit wirklich zählt. – robyschek

-1

Dieser Weg, es zu tun sein kann:

import random 

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

txt = "I'm not in a mood for [veggies], I rather have [fruit]."  
txt = txt.replace('[veggies]', random.choice(words['veggies'])).replace('[fruit]', random.choice(words['fruit'])) 
+1

Dies würde jedoch Dynamik verlieren. Das Beispiel wählt Wörter aus, die von Wörterbuchschlüsseln ersetzt werden sollen. Ihre Antwort codiert sie als Obst und Gemüse. – Hannu

+0

Danke für die Mühe, aber wie Hannu sagte, das ist hart codiert. Ich habe meine Frage bearbeitet, um das zu klären. –

1

ich es re.findall dann str.replace mit getan, aber ich fühle es ist nicht wirklich viel besser als Ihr entweder

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

found = re.findall('\[\w+\]', txt) 
for m in found: 
    txt = txt.replace(m, random.choice(words.get(m.strip('[]'), [m])), 1) 
+0

Ja, ziemlich ähnlich, aber gute Idee mit Regex obwohl! –

Verwandte Themen