97

I understand that we should use %s to concatenate a string rather than + in Python.

I could do any of:

hello = "hello"
world = "world"

print hello + " " + world
print "%s %s" % (hello, world)
print "{} {}".format(hello, world)
print ' '.join([hello, world])

But why should I use anything other than the +? It's quicker to write concatenation with a simple +. Then if you look at the formatting string, you specify the types e.g. %s and %d and such. I understand it could be better to be explicit about the type.

But then I read that using + for concatenation should be avoided even though it's easier to type. Is there a clear reason that strings should be concatenated in one of those other ways?

5
  • 33
    Who told you it's better?
    – yannis
    Commented Dec 7, 2015 at 10:38
  • 4
    %s isn't for concatenation, it's a conversion specification for string formatting derived from C's printf(3). There are cases to for using that or a concatenation operator; which you use should be based on judgment of the situation, not dogma. How easy it is to write the code is entirely irrelevant because you're only going to do that once.
    – Blrfl
    Commented Dec 7, 2015 at 13:33
  • I've refocused the question to just python (though I'm not a python person and there might still be glitches in the code). Please make sure that this is the question you are asking, make any appropriate updates and consider asking a different question if you are interested in C or Java.
    – user40980
    Commented Dec 7, 2015 at 20:46
  • 17
    And now we have the superior f-strings! print(f"{hello} {world}"), has readability of concatenation since variables are seen where they occur in the string, and is faster than str.format. Commented Aug 24, 2017 at 23:44
  • @EnricoBorba Agreed. The ease of reading interpolated strings is well known. F-strings are similar to the syntax used in shell, perl and other languages: echo "$hello $world".
    – jrw32982
    Commented Jan 6, 2021 at 21:33

5 Answers 5

99
  1. Readability. The format string syntax is more readable, as it separates style from the data. Also, in Python, %s syntax will automatically coerce any non str types to str; while concatenation only works with str, and you can't concatenate str with int.

  2. Performance. In Python str is immutable, so the left and right string have to be copied into the new string for every pair of concatenation. If you concatenate four strings of length 10, you will be copying (10+10) + ((10+10)+10) + (((10+10)+10)+10) = 90 characters, instead of just 40 characters. And things gets quadratically worse as the number and size of the string increases. Java optimizes this case some of the times by transforming the series of concatenation to use StringBuilder, but CPython doesn't.

  3. For some use cases, the logging library provide an API that uses format string to create the log entry string lazily (logging.info("blah: %s", 4)). This is great for improved performance if the logging library decided that the current log entry will be discarded by a log filter, so it doesn't need to format the string.

19
  • 40
    do you have any scientific or empiric source for #1? Because I think it's much much less readable (especially with more than 2 or three arguments)
    – Lovis
    Commented Dec 7, 2015 at 12:58
  • 6
    @L.Möller: I'm not quite sure what kind of source you expect from what is ultimately a subjective experience (ease of reading), but if you want my reasoning: 1) %s requires 2 extra characters per placeholder vs + requires minimum of 4 (or 8 if you follow PEP8, 13 if you coerce), 2) %s is enclosed in a single string, so it's easier to parse visually, with +, you has more moving parts: close string, operator, variable, operator, open string, 3) syntax coloring %s has one color for each functions: string and placeholder, with + you get three colorings: string, operator, and variable coloring.
    – Lie Ryan
    Commented Dec 7, 2015 at 13:28
  • 4
    @L.Möller: 4) I have the option to put longer format strings in a variable or dictionary, away from where formatting needs to be done, 5) the format string can be user specified from a config file, command args, or database, the same can't be said with concatenations. But yeah, I also wouldn't use %s when I have more than 4-5 things to interpolate, instead I'd use the %(varname)s variant or "{foo}".format() in Python. I think the explicit names improves readability for longer format strings with lots of interpolated variables.
    – Lie Ryan
    Commented Dec 7, 2015 at 13:46
  • 2
    I don't know whats "true", that's why I ask if you have evidence :-). Really agree with your second comment
    – Lovis
    Commented Dec 7, 2015 at 13:48
  • 7
    I find #2 to be suspect - do you have documented proof? I'm not supremely familiar with Java, but in C# concatenation is faster than string interpolation. I completely agree with #1 and really rely on that for deciding when to use which, but you have to remember interpolation requires an amount of string parsing and complexity where concatenation requires none of that. Commented Dec 7, 2015 at 14:02
54

Am I the only one who reads left to right?

To me, using %s is like listening to German speakers, where I have to wait until the end of a very long sentence to hear what the verb is.

Which of these is clearer at a quick glance?

"your %s is in the %s" % (object, location)

or

"your " + object + " is in the " + location  
12
  • 20
    Obviously this is subjective, since I find the first one more readable - and easier to write and edit. The second intermingles the text with code which obscures both and adds noise. For example it is easy to get the spaces wrong in the second.
    – JacquesB
    Commented Jul 27, 2016 at 6:28
  • 8
    @JacquesB I actually think your brain is so familiar with this format that you immediately jump to the brackets and are replacing the words instantly. Technically it isn't left-to-right reading, but that's perfectly fine. I find I do that too, so yes, 1 is easier to read because I know I have to deal with stupid spacing issues before and after the quotes in the second, and that is really slow to work with.
    – Nelson
    Commented Sep 29, 2016 at 2:37
  • 4
    The first one is way more readable for me because it has less "cruft" in the middle of the sentence. It's easier for my eye to glance to the end then it is for my brain to parse out the extra quotes, spaces, and pluses. Of course, I now much prefer Python 3.6 format strings: f"your {object} is in the {location}". Commented Jan 26, 2017 at 23:29
  • 9
    I also find it even harder to read and write when the variable needs to be surrounded with quotes itself. "your '" + object + "' is in the '" + location + "'"...I'm not even sure if I got that right just now... Commented Jan 26, 2017 at 23:32
  • 6
    I find f"your {object} is in the {kitchen}" (Python 3.6+) to be the most readable. Yay progress.
    – Graipher
    Commented Aug 26, 2018 at 7:48
12

An example clarifying readability argument:

print 'id: ' + id + '; function: ' + function + '; method: ' + method + '; class: ' + class + ' -- total == ' + total

print 'id: %s; function: %s; method: %s; class: %s --total == %s' % \
   (id, function, method, class, total)

(Note that second example is not only more readable but also easier to edit, you can change the template on one line and list of variables on another)

A separate issue is that %s code also converts to the string, otherwise you have to use str() call which is also less readable than a %s code.

1
  • 1
    I disagree with your first statement, but we can agree to differ, I was just about to post an answer along the lines of your second, so upvote
    – Mawg
    Commented Sep 29, 2016 at 7:13
9

Using + should not be avoided in general. In many cases is the correct approach. Using %s or .join() are only preferable in particular cases, and it is usually quite obvious when they are the better solution.

In your example you are concatenating three strings together, and the example using + is clearly the simplest and most readable, and therefore the recommended.

%s or .format() are useful if you want to interpolate strings or values in the middle of a larger string. Example:

print "Hello %s, welcome to the computer!" % name

In this case using %s it is more readable since you avoid chopping the first string into multiple segments. Especially if you are interpolating multiple values.

.join() is appropriate if you have a variable size sequence of strings and/or you want to concatenate multiple strings with the same separator.

4

Since the word order may change in different languages, the form with %s is imperative if you want to properly support the translation of strings in your software.

Not the answer you're looking for? Browse other questions tagged or ask your own question.