Python string concatenation vs format

I agree that the formatting is mostly used for readability, but since the release of f-strings in 3.6, the tables have turned in terms of performance. It is also my opinion that the f-strings are more readable/maintainable since 1) they can be read left-right like most regular text and 2) the spacing-related disadvantages of concatenation are avoided since the variables are in-string.

Running this code:

from timeit import timeit

runs = 1000000


def print_results(time, start_string):
    print(f'{start_string}\n'
          f'Total: {time:.4f}s\n'
          f'Avg: {(time/runs)*1000000000:.4f}ns\n')


t1 = timeit('"%s, %s" % (greeting, loc)',
            setup='greeting="hello";loc="world"',
            number=runs)
t2 = timeit('f"{greeting}, {loc}"',
            setup='greeting="hello";loc="world"',
            number=runs)
t3 = timeit('greeting + ", " + loc',
            setup='greeting="hello";loc="world"',
            number=runs)
t4 = timeit('"{}, {}".format(greeting, loc)',
            setup='greeting="hello";loc="world"',
            number=runs)

print_results(t1, '% replacement')
print_results(t2, 'f strings')
print_results(t3, 'concatenation')
print_results(t4, '.format method')

yields this result on my machine:

% replacement
Total: 0.3044s
Avg: 304.3638ns

f strings
Total: 0.0991s
Avg: 99.0777ns

concatenation
Total: 0.1252s
Avg: 125.2442ns

.format method
Total: 0.3483s
Avg: 348.2690ns

A similar answer to a different question is given on this answer.

Python string concatenation vs format
Print

In GEOG 485, we used the + operator for string concatenation to produce strings from multiple components to then print them out or use them in some other way, as in the following two examples:

print('The feature class contains ' + str(n) + ' point features.') 

queryString = '"'+ fieldName+ '" = ' + "'" + countryName + "'" 

An alternative to this approach using string concatenation is to use the string method format(…). When this method is invoked for a particular string, the string content is interpreted as a template in which parts surrounded by curly brackets {…} should be replaced by the variables given as parameters to the method. Here is how the two examples from above would look in this approach:

print('The feature class contains {0} point features.'.format(n) ) 

queryString = '"{0}" = \'{1}\''.format(fieldName, countryName) 

In both examples, we have a string literal '….' and then directly call the format(…) method for this string literal to give us a new string in which the occurrences of {…} have been replaced. In the simple form {i} used here, each occurrence of this pattern will be replaced by the i-th parameter given to format(…). In the second example, {0} will be replaced by the value of variable fieldName and {1} will be replaced by variable countryName. Please note that the second example will also use \' to produce the single quotes so that the entire template could be written as a single string. The numbers within the curly brackets can also be omitted if the parameters should be inserted into the string in the order in which they appear.

The main advantages of using format(…) are that the string can be a bit easier to produce and read as in particular in the second example, and that we don’t have to explicitly convert all non-string variables to strings with str(…). In addition, format allows us to include information about how the values of the variables should be formatted. By using {i:n}, we say that the value of the i-th variable should be expanded to n characters if it’s less than that. For strings, this will by default be done by adding spaces after the actual string content, while for numbers, spaces will be added before the actual string representation of the number. In addition, for numbers, we can also specify the number d of decimal digits that should be displayed by using the pattern {i:n.df}. The following example shows how this can be used to produce some well-formatted list output:

items = [('Maple trees', 45.232 ),  ('Pine trees', 30.213 ), ('Oak trees', 24.331)]

for i in items: 

    '{0:20} {1:3.2f}%'.format(i[0], i[1]) 

Output:

Maple trees                          45.23% 
Pine trees                           30.21% 
Oak trees                            24.33% 

The pattern {0:20} is used here to always fill up the names of the tree species in the list with spaces to get 20 characters. Then the pattern {1:3.2f} is used to have the percentage numbers displayed as three characters before the decimal point and two digits after. As a result, the numbers line up perfectly.

The format method can do a few more things, but we are not going to go into further details here. Check out this page about formatted output if you would like to learn more about this.

What are the benefits of using the format method instead of string concatenation?

The main advantages of using format(…) are that the string can be a bit easier to produce and read as in particular in the second example, and that we don't have to explicitly convert all non-string variables to strings with str(…).

What is the best way to concatenate strings in Python?

One of the most popular methods to concatenate two strings in Python (or more) is using the + operator. The + operator, when used with two strings, concatenates the strings together to form one.

Are F strings better than concatenation?

From a readability standpoint, f-string literals are more aesthetically pleasing and easier to read than string concatenation.

How do you append a string formatted in Python?

We can perform string concatenation using following ways:.
Using + operator..
Using join() method..
Using % operator..
Using format() function..
Using f-string (Literal String Interpolation).