Reputation: 1447
I feel like this would have been asked before, but could not find anything.
In python, if you want to insert a var into a string, there are (at least) two ways of doing so.
Using the +
operator
place = "Alaska"
adjective = "cold"
sentence = "I live in "+place+"! It's very "+adjective+"!"
# "I live in Alaska! It's very cold!"
And using a tuple
place = "Houston"
adjective = "humid"
sentence = "I live in %s! It's very %s!" % (place, adjective)
# "I live in Houston! It's very humid!"
Why would one use the tuple method over using +
? The tuple format seems a lot more obfuscated. Does it provide an advantage in some cases?
The only advantage I can think of is you don't have to cast types with the latter method, you can use %s
to refer to a
, where a = 42
, and it will just print it as a string, as opposed to using str(a)
. Still that hardly seems like a significant reason to sacrifice readability.
Upvotes: 2
Views: 166
Reputation: 1122392
The string % (value, value, ..)
syntax is called a string formatting operation, and you can also apply a dictionary, it is not limited to just tuples. These days you'd actually want to use the newer str.format()
method as it expands on the offered functionality.
String formatting is about much more than just inserting strings in-between other strings. You'd use it because
you can configure each interpolation, based on the type of object you are trying to insert into the string. You can configure how floating point numbers are formatted, how dates are formatted (with str.format()
), etc.
you can adjust how the values are padded or aligned; you could create columns with values all neatly right-aligned in fixed-width columns, for example.
especially with str.format()
, the various aspects you can control can either be hardcoded in the string template, or taken from additional variables (the older %
string formatting operation only allows for field width and numeric precision can be made dynamic).
you can define and store the string templates independently, applying values you want to interpolate separately:
template = 'Hello {name}! How do you find {country} today?'
result = template.format(**user_information)
What fields are available can be larger than what you actually use in the template.
it can be faster; each +
string concatenation has to create a new string object. Add up enough +
concatenations and you end up creating a lot of new string objects that are then discarded again. String formatting only has to create one final output string.
string formatting is actually far more readable than using concatenation, as well as being more maintainable. Try to use +
or string formatting on a multiline string with half a dozen different values to be interpolated. Compare:
result = '''\
Hello {firstname}!
I wanted to send you a brief message to inform you of your updated
scores:
Enemies engaged: {enemies.count:>{width}d}
Enemies killed: {enemies.killed:>{width}d}
Kill ratio: {enemies.ratio:>{width}.2%}
Monthly score: {scores.month_to_date:0{width}d}
Hope you are having a great time!
{additional_promotion}
'''.format(width=10, **email_info)
with
result = '''\
Hello ''' + firstname + '''!
I wanted to send you a brief message to inform you of your updated
scores:
Enemies engaged: ''' + str(email_info['enemies'].count).rjust(width) + '''
Enemies killed: ''' + str(email_info['enemies'].killed).rjust(width) + '''
Kill ratio: ''' + str(round(email_info['enemies'].ratio * 100, 2)).rjust(width - 1) + '''%
Monthly score: ''' + str(email_info['scores'].month_to_date).zfill(width) + '''
Hope you are having a great time!
''' + email_info['additional_promotion'] + '''
'''
Now imagine having to re-arrange the fields, add some extra text and a few new fields. Would you rather do that in the first or second example?
Upvotes: 4
Reputation: 27595
For a lot of reasons. One good reason is that not always you can or want to use separated strings, because they are already neatly arranged in a list or tuple:
strings = ["one", "two", "three"]
print "{}, {} and {}".format(*strings)
> one, two and three
Upvotes: 4