Reputation: 593
I have a string with unknown number of %s
that need to be formatted with a single string.
For instance, if I had the string "%s some %s words %s"
and wanted to format it with the word house
it should output "house some house words house"
Doing the following gives me an error:
>>> "%s some %s words %s" % ("house")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
So, I decided to do the following, which works but seem to be overly complex for such a simple problem.
var = "house"
tup = (var,)
while True:
try:
print "%s some %s words %s" % tup
break
except:
tup += (var,)
Is there a more pythonic way of doing this?
Upvotes: 3
Views: 1622
Reputation: 13016
Here are a few options:
Using str.format
is the most pythonic way and pretty simple to read. Either style is popular:
'{0} some {0} words {0}'.format('house')
'{word} some {word} words {word}'.format(word='house')
In a comment you mentioned preserving the original format string because of other legacy code. You could hack around that like so:
'%s some %s words %s'.replace('%s', '{0}').format('house')
(I don't recommend it but you could "short circuit" this idea line by using 'house'
in the replace call instead of '{0}'
.)
That said, I really think changing the template string in the first place is a better idea.
One more alternative comes to mind after glancing at the string
docs: the older string.Template
class. By default it substitutes $
-based values, but you can subclass it overriding the delimiter character. For example:
class MyTemplate(Template):
"""
Overriding default to maintain compatibility with legacy code.
"""
delimiter = '%'
t = MyTemplate('%s some %s words %s')
t.substitute(s='house')
Remember this is less common but you could write it once and re-use it every time you work with a string like this (assuming there's only one input value being substituted in). Writing it once is Pythonic at least!
In Python 3.6, Ruby-style string interpolation is another option that the community hasn't come to a consensus on yet. For example:
s = 'house'
f'{s} some {s} words {s}'
Upvotes: 5
Reputation: 184091
If you know for sure you're subbing %s
you can do it like this:
var = "house"
tup = (var,)
txt = "%s some %s words %s"
print txt % (tup * txt.count("%s"))
But a better solution is to use str.format()
which uses a different syntax, but lets you specify items by number, so you can reuse them:
var = "house"
txt = "{0} some {0} words {0}"
print txt.format(var)
Upvotes: 5