0

I am currently trying to replace the occurrence of a number x with the xth argument in a string. Here is my code:

def simple_format(format, *args):
    res = format.replace("%", "")
    for x in res:
        if (isinstance(x, int)):
            res = res.replace(x, args(x))
     return res

The first replace is used to remove the occurrence of % in the string and the next is to check if the variable encountered is a number and if it is, replacing it with the argument.

For example, simple_format("hello %0", "world", "Ben") should return "hello world".The desired output is not achieved. What is the mistake? Is there any way to do it using replace method? Thanks in advance.

Shsa
  • 17
  • 10

2 Answers2

1

Your current approach is bugged, as x will always be type str, so the isinstance check will always be False. Plus, even if you fixed that, your code will replace every single digit to its index in args (as long as you also change args(x) to args[x]).

I would use a regex substitution to convert your string to a proper format literal. Then you can use string format to insert the arguments.

import re
def simple_format(format, *args):
    new = re.sub(r"%(\d+)", r"{\1}", format)
    return new.format(*args)

print(simple_format("hello %0", "world", "Ben"))
# hello world
Taku
  • 31,927
  • 11
  • 74
  • 85
  • Isn't the intent to write her own version of format, not fall back to the built in method? – dashiell Jun 29 '18 at 14:44
  • Thank you!! But I am beginner. So it would be better, if I do it without any complicated stuff. Is there any other way, other than using regex – Shsa Jun 29 '18 at 14:44
  • @dashiell I don't see the OP mentioning about that – Taku Jun 29 '18 at 14:47
1

Here is a more basic approach IMO, and probably more readable:

import re

s = 'hello %0, how %2 do you come to %1?'

replacements = ['world','stack overflow','often']

for match in re.findall(r'\%[0-9]+', s):
    s = re.sub(match, replacements[int(re.sub(r'\%','',match))], s)

Output:

'hello world, how often do you come to stack overflow?'

Explanation:

re.findall(r'\%[0-9]+', s) finds all %0, %2, %1, etc. in the string s

For each of those matches, use re.sub() to substitute in the corresponding string from replacements. Iterate through all matches to be replaced.

rahlf23
  • 8,869
  • 4
  • 24
  • 54
  • Thank you!! But can't it be done using replace method? – Shsa Jun 29 '18 at 14:53
  • If you were simply replacing the `%` symbols and nothing else, then sure. However, it sounds from your OP that you are interested in having your replacement dependent on the `int` following the `%` symbol. In which case, it's more advantageous to use `re.sub()` to specify the pattern you are interested in. – rahlf23 Jun 29 '18 at 14:55