4

So I'm programming a text game in Python 3.4 that requires the use of the print() function very often to display variables to the user.

The two ways I've always done this is with string formatting and string concatenation:

print('{} has {} health left.'.format(player, health))

And,

print(player + ' has ' + str(health) + ' health left.')

So which is better? They're both equally as readable and quick to type, and perform exactly the same. Which one is more Pythonic and why?

Question asked as I couldn't find an answer for this on Stack Overflow that wasn't concerned with Java.

Alice
  • 588
  • 1
  • 8
  • 25
  • 1
    A partial answer can be found at [Any reason not to use '+' to concatenate two strings?](http://stackoverflow.com/questions/10043636/any-reason-not-to-use-to-concatenate-two-strings) – Wiktor Stribiżew Jan 05 '17 at 09:28
  • 1
    Well, from semantic and readable angle, using `format` seems better. – Acepcs Jan 05 '17 at 09:31
  • depends on how many strings should be concatenated and how sophisticated the format is – RomanPerekhrest Jan 05 '17 at 09:33
  • @WiktorStribiżew I've taken a look at the post, but that debate seems to be over string concatenation and the `.join()` function rather than the `.format()` function. I would like to see an explicit answer so that people with the same question as me will not have to search through fragments of half relevant discussions in the future. Thank you for the link though, it was interesting to read about the `.join()` function in more detail. – Alice Jan 05 '17 at 09:34
  • @RomanPerekhrest For a text based game, the format will be basic simple sentences. About 4 or 5 different variables may need to be printed within the same `print()`. – Alice Jan 05 '17 at 09:36
  • 1
    I found another question on SO that seems closer to what you are looking for: [Python string formatting: % vs concatenation](http://stackoverflow.com/questions/34619384/python-string-formatting-vs-concatenation). It also touches upon `.format` there. – Wiktor Stribiżew Jan 05 '17 at 09:38
  • The pythonic way is to use string formatting, definitly. Because it's much more readable. – bruno desthuilliers Jan 05 '17 at 11:13

3 Answers3

8

Depends upon how long your string is and how many variables. For your use case I believe string.format is better as it has a better performance and looks cleaner to read.

Sometimes for longer strings + looks cleaner because the position of the variables are preserved where they should be in the string and you don't have to move your eyes around to map the position of {} to the corresponding variable.

If you can manage to upgrade to Python 3.6 you can use the newer more intuitive string formatting syntax like below and have best of both worlds:

player = 'Arbiter'
health = 100
print(f'{player} has {health} health left.')

If you have a very large string, I recommend to use a template engine like Jinja2 (http://jinja.pocoo.org/docs/dev/) or something along the line.

Ref: https://www.python.org/dev/peps/pep-0498/

Tonechas
  • 13,398
  • 16
  • 46
  • 80
Eddie
  • 1,043
  • 8
  • 14
  • That's what I was thinking, since matching up the `{}` to the corresponding variable on long lines of code can be difficult and it's easy to make a mistake and look at the wrong variable for that position. Looks like your example fixes that with increased readability. I will definitely get Python 3.6 for that, however, my project is heavily built around the `pygame` module, do you know if Python 3.6 supports `pygame`? – Alice Jan 05 '17 at 10:08
  • @Arbiter If Im not mistaken `pygame` works fine with Python 3.6. Last time I was running `Kivy` which depends upon `pygame`. – Eddie Jan 05 '17 at 10:11
  • 3
    @Arbiter you can do something like the following too: `'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W')` which is very readable in long strings. – juanpa.arrivillaga Jan 05 '17 at 10:30
6

format() is better:

  1. Better, performance-wise.
  2. clearer. You can see how the sentence looks like and what are the parameters, you don't have a bunch of + and ' all around.
  3. Gives you more features for example how many places after zero in a floating point, thus more flexible to changes.
Hanan
  • 1,395
  • 4
  • 18
  • 29
  • When you say better 'performance-wise', do you mean better as in faster and more efficient? I was thinking of using the `time` module and `time.clock()` to see which method is fastest with many variables. – Alice Jan 05 '17 at 10:12
  • concat 4 strings goes like this: 1+2, (1+2)+3, (1+2+3)+4 -> thats much more string objects that are allocated and much more string operations. Thats my very high-level explanation. But I'm pretty sure measurement will give the prove. – Hanan Jan 05 '17 at 10:34
5

It depends on the quantity and type of objects you're combining, as well as the kind of output you want.

>>> d = '20160105'
>>> t = '013640'
>>> d+t
'20160105013640'
>>> '{}{}'.format(d, t)
'20160105013640'
>>> hundreds = 2
>>> fifties = 1
>>> twenties = 1
>>> tens = 1
>>> fives = 1
>>> ones = 1
>>> quarters = 2
>>> dimes = 1
>>> nickels = 1
>>> pennies = 1
>>> 'I have ' + str(hundreds) + ' hundreds, ' + str(fifties) + ' fifties, ' + str(twenties) + ' twenties, ' + str(tens) + ' tens, ' + str(fives) + ' fives, ' + str(ones) + ' ones, ' + str(quarters) + ' quarters, ' + str(dimes) + ' dimes, ' + str(nickels) + ' nickels, and ' + str(pennies) + ' pennies.'
'I have 2 hundreds, 1 fifties, 1 twenties, 1 tens, 1 fives, 1 ones, 2 quarters, 1 dimes, 1 nickels, and 1 pennies.'
>>> 'I have {} hundreds, {} fifties, {} twenties, {} tens, {} fives, {} ones, {} quarters, {} dimes, {} nickels, and {} pennies.'.format(hundreds, fifties, twenties, tens, fives, ones, quarters, dimes, nickels, pennies)
'I have 2 hundreds, 1 fifties, 1 twenties, 1 tens, 1 fives, 1 ones, 2 quarters, 1 dimes, 1 nickels, and 1 pennies.'
>>> f'I have {hundreds} hundreds, {fifties} fifties, {twenties} twenties, {tens} tens, {fives} fives, {ones} ones, {quarters} quarters, {dimes} dimes, {nickels} nickels, and {pennies} pennies.'
'I have 2 hundreds, 1 fifties, 1 twenties, 1 tens, 1 fives, 1 ones, 2 quarters, 1 dimes, 1 nickels, and 1 pennies.'

It is much easier to create without error a large format string than it is to do a lot of concatenation, too. Add in the fact that format strings can handle actual formatting, like alignment or rounding, and you'll soon leave concatenation for only the simplest cases, as shown above.

TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
  • Excellent examples, I can see now that string formatting is far more versatile, readable and simplistic than string concatenation when it comes to many variables. Thanks! – Alice Jan 05 '17 at 10:05