Reputation: 101
I'd like to replace occurrences of string with different values (from dictionary).
string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {1: 'hi', 2: 'there', 3: 'bla'}
Expected:
string = 'asfd hi fdsfd there ffds bla asdf'
I've tried several solutions particularly with .replace or re.sub but still didn't find a good one.
Upvotes: 1
Views: 2306
Reputation: 5774
A one-line solution:
string.replace('@@@', '{}', len(kv)).format(*kv.values())
Short explanation:
'@@@'
strings with the python string formatting identifier '{}'
. len(kv)
reduces the number of replaces to the length of the dict, avoiding IndexError
when the dict has less elements than the number of '@@@'
in the stringkv.values()
*kv.values()
and pass this as argument to the string format
method.Sample code execution:
Input
string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {'1': 'hi', '2': 'there', '3': 'bla'}
And output
string.replace('@@@', '{}', len(kv)).format(*kv.values())
#Out: 'asfd hi fdsfd there ffds bla asdf'
Advantage of this solution:
No explicit looping (explicit looping is almost always a bad idea in python) and only one line of code. Furthermore this is also working when the number of '@@@'
is less **or greater than the number of values in kv
**, when the count
parameter in str.replace
is specified.
This leads to the final and 99% failsafe variant of my solution, using the len
of the dict as count
argument in replace
:
string.replace('@@@', '{}', len(kv)).format(*kv.values())
Upvotes: 8
Reputation: 3419
You can use re.sub
to get the job done with out any sorting
Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl. If the pattern isn’t found, string is returned unchanged. repl can be a string or a function; if it is a string, any backslash escapes in it are processed.
import re
string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {'1': 'hi', '2': 'there', '3': 'bla'}
class repl:
def __init__(self):
self.called=0
def __call__(self,match):
self.called+=1
return kv[str(self.called)]
print(re.sub('@@@',repl(),string))
OUTPUT
asfd hi fdsfd there ffds bla asdf
Upvotes: 3
Reputation: 7585
kv = {'1': 'hi', '2': 'there', '3': 'bla'}
string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
string_list=string.split('@@@')
string_list_out=[]
for i in range(len(string_list)):
if i==0:
string_list_out.append(string_list[0])
else:
string_list_out.append(kv[str(i)])
string_list_out.append(string_list[i])
string_list_out=''.join(string_list_out)
print(string_list_out)
'asfd hi fdsfd there ffds bla asdf'
Upvotes: 0
Reputation: 16772
string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {1: 'hi', 2: 'there', 3: 'bla'}
for k,v in kv.items():
string = string.replace('@@@', v, 1)
print(string)
OUTPUT:
asfd hi fdsfd there ffds bla asdf
Upvotes: 0