user4250027
user4250027

Reputation:

Python 3: Formatting a string with multiple same keywords but unique strings to replace them

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

Answers (5)

Mark Tolonen
Mark Tolonen

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

Pynchia
Pynchia

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

Plopern
Plopern

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

Open AI - Opting Out
Open AI - Opting Out

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

Mureinik
Mureinik

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

Related Questions