Reputation:
I'm wondering how to use a list to format multiple of the same keyword in Python 3.4. The way I have it set up is a user can pass in a string that has multiple keywords for names that the program will generate in their place, and the result should be a sentence with the keywords replaced with names.
I have already created a method to generate the names based on how many the program sees in the strings the user passes in, but cannot replace them at once because of the nature of the string. Since the string has multiple of the same keyword (for example {name}), I need to be able to replace each one of them with a unique string. Is that possible in Python 3.4?
The string the user passes in could be
"{name} had a wonderful day at the park, but then {name} came and ruined it"
and after the program has generated the names it should be
"John had a wonderful day at the park, but then Bob came and ruined it"
Cheers.
EDIT: To add, I didn't find anything about using lists or having multiple keywords but unique replacements, so if I have to do it another way than replace it's OK too.
Upvotes: 2
Views: 229
Reputation: 177901
If you have pre-generated a list of items for each replacement based on how many times they occur, you can use re.sub
to programmatically pick the next item from the list. This will have much better performance than str.replace
, esp. if you have a large dictionary of keywords and and a large text.
For example:
import re
# Function to look up an item and return the next thing in its list.
def replace(m):
return D[m.group(1)].pop(0)
D = {'name' : ['John','Bob'], 'place' : ['park']}
text = "{name} had a wonderful day at the {place}, but then {name} came and ruined it"
new_text = re.sub('{(.*?)}',replace,text)
print(new_text)
Output:
John had a wonderful day at the park, but then Bob came and ruined it
It seems like you'd want a different variable for different names, however. Then you can just use format
with a dictionary:
import re
D = {'name1':'John', 'name2':'Bob', 'place':'park'}
text = "{name1} had a wonderful day at the {place}, but then {name2} came and ruined it. {name2} is a jerk!"
print(text.format(**D))
Output:
John had a wonderful day at the park, but then Bob came and ruined it. Bob is a jerk!
Upvotes: 2
Reputation: 11586
In case the phrase is always well spaced as in the example, you can do
s = "{name} had a wonderful day at the park, but then {name} came and ruined it"
names = ['John', 'Bob']
ni = iter(names)
outs = ' '.join(next(ni) if el=='{name}' else el for el in s.split())
print(outs)
which produces
'John had a wonderful day at the park, but then Bob came and ruined it'
Upvotes: 0
Reputation: 43
If I understand you right, this should work:
first_name = Bob
second_name = Sam
"%s had a wonderful day at the park, but then %s came and ruined it" % (first_name, second_name)
Probably the cleanest way to do it
Upvotes: 0
Reputation: 24153
You can use the count
parameter:
>>> s = "{name} had a wonderful day at the park, but then {name} came and ruined it"
>>> s = s.replace('{name}', 'John', count=1)
>>> s
'John had a wonderful day at the park, but then {name} came and ruined it'
>>> s = s.replace('{name}', 'Bob', count=1)
>>> s
'John had a wonderful day at the park, but then Bob came and ruined it'
Upvotes: 2
Reputation: 311823
You can use string.replace
with the optional count
parameter and limit it to only replace one name each time:
>>> names = ['John', 'Bob']
>>> message = "{name} had a wonderful day at the park, but then {name} came and ruined it"
>>> i = 0;
>>> while '{name}' in message:
... message = message.replace('{name}', names[i], 1)
... i += 1
...
>>> message
'John had a wonderful day at the park, but then Bob came and ruined it'
Upvotes: 3