How can I concatenate str and int objects?

106,117

The problem here is that the + operator has (at least) two different meanings in Python: for numeric types, it means "add the numbers together":

>>> 1 + 2
3
>>> 3.4 + 5.6
9.0

... and for sequence types, it means "concatenate the sequences":

>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> 'abc' + 'def'
'abcdef'

As a rule, Python doesn't implicitly convert objects from one type to another1 in order to make operations "make sense", because that would be confusing: for instance, you might think that '3' + 5 should mean '35', but someone else might think it should mean 8 or even '8'.

Similarly, Python won't let you concatenate two different types of sequence:

>>> [7, 8, 9] + 'ghi'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list

Because of this, you need to do the conversion explicitly, whether what you want is concatenation or addition:

>>> 'Total: ' + str(123)
'Total: 123'
>>> int('456') + 789
1245

However, there is a better way. Depending on which version of Python you use, there are three different kinds of string formatting available2, which not only allow you to avoid multiple + operations:

>>> things = 5
>>> 'You have %d things.' % things  # % interpolation
'You have 5 things.'
>>> 'You have {} things.'.format(things)  # str.format()
'You have 5 things.'
>>> f'You have {things} things.'  # f-string (since Python 3.6)
'You have 5 things.'

... but also allow you to control how values are displayed:

>>> value = 5
>>> sq_root = value ** 0.5
>>> sq_root
2.23606797749979
>>> 'The square root of %d is %.2f (roughly).' % (value, sq_root)
'The square root of 5 is 2.24 (roughly).'
>>> 'The square root of {v} is {sr:.2f} (roughly).'.format(v=value, sr=sq_root)
'The square root of 5 is 2.24 (roughly).'
>>> f'The square root of {value} is {sq_root:.2f} (roughly).'
'The square root of 5 is 2.24 (roughly).'

Whether you use % interpolation, str.format(), or f-strings is up to you: % interpolation has been around the longest (and is familiar to people with a background in C), str.format() is often more powerful, and f-strings are more powerful still (but available only in Python 3.6 and later).

Another alternative is to use the fact that if you give print multiple positional arguments, it will join their string representations together using the sep keyword argument (which defaults to ' '):

>>> things = 5
>>> print('you have', things, 'things.')
you have 5 things.
>>> print('you have', things, 'things.', sep=' ... ')
you have ... 5 ... things.

... but that's usually not as flexible as using Python's built-in string formatting abilities.


1 Although it makes an exception for numeric types, where most people would agree on the 'right' thing to do:

>>> 1 + 2.3
3.3
>>> 4.5 + (5.6+7j)
(10.1+7j)

2 Actually four, but template strings are rarely used, and are somewhat awkward.


Other Resources:

Share:
106,117

Related videos on Youtube

Zero Piraeus
Author by

Zero Piraeus

Desouffle

Updated on February 26, 2022

Comments

  • Zero Piraeus
    Zero Piraeus about 2 years

    If I try to do the following:

    things = 5
    print("You have " + things + " things.")
    

    I get the following error in Python 3.x:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: can only concatenate str (not "int") to str
    

    ... and a similar error in Python 2.x:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: cannot concatenate 'str' and 'int' objects
    

    How can I get around this problem?

    • Trenton McKinney
      Trenton McKinney over 3 years
      FYI: there are 9 answers deleted as duplicates to this question. Do not post answers with content covered in the accepted answer. They will be deleted, as per Flag Duplicate Answers on the same Question.
    • Trenton McKinney
      Trenton McKinney over 2 years
      FYI: There are now 11 answers deleted as duplicates. All of the methods pertaining to the question in the OP, are covered in the accepted answer. If you post an answer that's already covered, it will be deleted as a duplicate. There is no additional value for SO to keep multiple answers with the same solution. Instead, upvote existing answers.