Brian C Brian C - 1 year ago 56
Python Question

Why use tuples when inserting vars into strings in Python?

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


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
to refer to
, where
a = 42
, and it will just print it as a string, as opposed to using
. Still that hardly seems like a significant reason to sacrifice readability.

Answer Source

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. 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
        Enemies engaged: {enemies.count:>10d}
        Enemies killed:  {enemies.killed:>10d}
        Kill ratio:      {enemies.ratio:>10.2%}
        Monthly score:   {scores.month_to_date:010d}
    Hope you are having a great time!


    result = '''\
    Hello ''' + firstname + '''!
    I wanted to send you a brief message to inform you of your updated
        Enemies engaged: ''' + str(email_info['enemies'].count).rjust(10) + '''
        Enemies killed:  ''' + str(email_info['enemies'].killed).rjust(10) + '''
        Kill ratio:      ''' + str(round(email_info['enemies'].ratio * 100, 2)).rjust(9) + '''%
        Monthly score:   ''' + str(email_info['scores'].month_to_date).zfill(10d) + '''
    Hope you are having a great time!
    ''' + email_info['additional_promotion'] + '''