3

Let's say I have a string s

s = "?, ?, ?, test4, test5"

I know that there are three question marks, and I want to replace each question mark accordingly with the following array

replace_array = ['test1', 'test2', 'test3']

to obtain

output = "test1, test2, test3, test4, test5"

is there a function in Python, something like s.magic_replace_func(*replace_array) that will achieve the desired goal?

Thanks!

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
Michael
  • 7,087
  • 21
  • 52
  • 81

4 Answers4

5

Use str.replace and replace '?' with '{}', then you can simply use the str.format method:

>>> s = "?, ?, ?, test4, test5"
>>> replace_array = ['test1', 'test2', 'test3']
>>> s.replace('?', '{}', len(replace_array)).format(*replace_array)
'test1, test2, test3, test4, test5'
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
4

Use str.replace() with a limit, and loop:

for word in replace_array:
    s = s.replace('?', word, 1)

Demo:

>>> s = "?, ?, ?, test4, test5"
>>> replace_array = ['test1', 'test2', 'test3']
>>> for word in replace_array:
...     s = s.replace('?', word, 1)
... 
>>> s
'test1, test2, test3, test4, test5'

If your input string doesn't contain any curly braces, you could also replace the curly question marks with {} placeholders and use str.format():

s = s.replace('?', '{}').format(*replace_array)

Demo:

>>> s = "?, ?, ?, test4, test5"
>>> s.replace('?', '{}').format(*replace_array)
'test1, test2, test3, test4, test5'

If your real input text already has { and } characters, you'll need to escape those first:

s = s.replace('{', '{{').replace('}', '}}').replace('?', '{}').format(*replace_array)

Demo:

>>> s = "{?, ?, ?, test4, test5}"
>>> s.replace('{', '{{').replace('}', '}}').replace('?', '{}').format(*replace_array)
'{test1, test2, test3, test4, test5}'
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2

And a regular expression with function approach - which scans the string only once, is more flexible in terms of adapting the replacement pattern, doesn't possibly conflict with existing formatting operations, and can be changed to provide default values if not enough replacements are available... :

import re

s = "?, ?, ?, test4, test5"
replace_array = ['test1', 'test2', 'test3']
res = re.sub('\?', lambda m, rep=iter(replace_array): next(rep), s)
#test1, test2, test3, test4, test5
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • 1
    This is what I was thinking, although since I dislike regexes I went with `to_replace = iter(replace_array)` and `''.join([c if c != '?' else next(to_replace) for c in s])`. Using a regular expression is more adaptable for the pattern being replaced, I have to admit. – DSM Feb 20 '14 at 16:37
2

Try this:

s.replace('?', '{}').format(*replace_array)
=> 'test1, test2, test3, test4, test5'

Even better, if you substitute the ? signs with {} placeholders you can call format() directly, without calling replace() first. After that, format() takes care of everything.

Óscar López
  • 232,561
  • 37
  • 312
  • 386