Reputation: 1435
Is there any way I can only replace only the first argument only in string formatting? Like in this:
"My quest is {test}{}".format(test="test")
I want the output to be:
"My quest is test {}
The second {}
arg I will replace later.
I know I can create a string like:
"My quest is {test}".format(test="test")
and later combine it with remaining string and create new string, but can I do it in one go?
Upvotes: 23
Views: 11730
Reputation: 443
You can use replace functionality in python and replace the strings instead of using format, this allows you to do it in any order and replace one string at a time also
x = "{param1} test {param2}"
x = x.replace("{param1}", param1)
x = x.replace("{param2}", param2)
Upvotes: 3
Reputation: 3547
Use named parameters and leave the others to be replaced with the same.
Use this a lot to "normalize strings" so they fit general patterns upfront:
>>> x = "foo {test} bar {other}"
>>> x = x.format(test='test1', other='{other}')
>>> x
'foo test1 bar {other}'
>>> x = x.format(other='other1')
>>> x
'foo test1 bar other1'
Upvotes: 13
Reputation: 1650
The correct way to achieve this would probably be to subclass string.Formatter class and use its instance instead of the string method:
from string import Formatter
class IncrementalFormatter(Formatter):
pass # your implementation
f = IncrementalFormatter()
f.format("hello {name}", name="Tom")
The following Formatter
methods would have to be overwritten:
get_value()
should return some special object instead of raising LookupError
.get_field()
should save field_name
argument into this object (or proceed normally if the object is not our special object).convert_field()
should just save conversion
argument into this object and do no conversion (or proceed normally...).format_field()
should reconstruct field format string from the special object using its field_name
and conversion
attributes and format_spec
argument of this method (or proceed normally...).So, for example:
f.format("{greet} {who.name!r:^16s}", greet="hello")
should result in "hello {who.name!r:^16s}"
, where "who.name"
is field_name
, "r"
is conversion
, "^16s"
is format_spec
and all these three values were re-combined back into "{who.name!r:^16s}"
, so that it can be used in the next formatting pass.
Additional note: the special object should return itself upon access of any attribute (with .
) or item (with []
).
Upvotes: 0
Reputation: 104762
If you know when you set up the format string that you'll only be replacing a subset of the values, and you want some other set to remain, you can escape the ones you're not going to fill right away by doubling the brackets:
x = "foo {test} bar {{other}}".format(test="test") # other won't be filled in here
print(x) # prints "foo test bar {other}"
print(x.format(other="whatever")) # prints "foo test bar whatever"
Upvotes: 28
Reputation: 388023
You would have to write your own format function that only makes a single replacement. For example, to give you something to start with (note that this is somewhat vulnerable to bad format strings):
import re
def formatOne(s, arg):
return re.sub('\{.*?\}', arg, s, count=1)
Used like this:
>>> s = "My quest is {test}{}"
>>> formatOne(s, 'test')
'My quest is test{}'
>>> formatOne(_, ' later')
'My quest is test later'
Upvotes: 2
Reputation: 160567
The only way you can replace it in the same line is if you replace "{test}"
with another bracket. I.e:
s = "My quest is {test}".format(test="test {}").format('testing')
but that doesn't make much sense because you could've just done:
s = "My quest is {test} {}".format('testing', test="test {}")
immediately.
You could keep the result of:
s = "My quest is {test}".format(test="test {}")
So s
has a bracket inside it waiting to get replaced and call format
on it later on if you need to.
Upvotes: 1