I have a code similar to this:
s = some_template
s = s.replace('<HOLDER1>',data1)
s = s.replace('<HOLDER2>',data2)
s = s.replace('<HOLDER4>',data3)
... #(about 30 similar lines)
where data1/data2/etc is often a call to a function which might take a while to calculate. for example:
s = s.replace('<HOLDER5>',calc_factorial(1000))
in order to save on runtime, i want the string.replace() method to calculate the new value only if the old value is found in str. this can be achieved by:
if '<HOLDER1>' in str:
s = s.replace('<HOLDER1>',data1)
if '<HOLDER2>' in str:
s = s.replace('<HOLDER2>',data2)
if '<HOLDER3>' in str:
s = s.replace('<HOLDER3>',data3)
...
but i don't like this solutions because it takes double the number of lines of code which will be really messy and also finds the old value in s twice for each holder..
any ideas?
Thanks!
CodePudding user response:
str
is immutable. You can't change it, only creating a new instance is allowed.
You could do something like:
def replace_many(replacements, s):
for pattern, replacement in replacements:
s = s.replace(pattern, replacement)
return s
without_replacements = 'this_will_be_replaced, will it?'
replacements = [('this_will_be_replaced', 'by_this')]
with_replacements = replace_many(replacements, without_replacements)
You can easily make it lazy:
def replace_many_lazy(replacements, s):
for pattern, replacement_func in replacements:
if pattern in s:
s = s.replace(pattern, replacement_func())
return s
without_replacements = 'this_will_be_replaced, will it?'
replacements = [('this_will_be_replaced', lambda: 'by_this')]
with_replacements = replace_many_lazy(replacements, without_replacements)
...now you don't do the expensive computation unless necessary.
CodePudding user response:
a couple of suggestions. First, please do not shadow the builtin str name.
Next, the index of function might be useful, however, you will need a try-catch block if the Holder doesn't exist in the string.
s = "my name is <HOLDER1>. What's yours? <HOLDER2>"
s.index("<HOLDER1>")
11
s.index("<HOLDER3>")
Traceback (most recent call last):
File "C:\Users\klavl\AppData\Local\Programs\Python\Python310\lib\code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
ValueError: substring not found
This would be the structure.
s = "my name is <HOLDER1>. What's yours? <HOLDER2>"
if (index := s.index("<HOLDER1>")) >= 0:
s = s[:index] "MYNAME" s[index len("<HOLDER1>"):]
s
"my name is MYNAME. What's yours? <HOLDER2>"