web-dev-qa-db-fra.com

Comment concaténer des objets str et int?

Si j'essaie de faire ce qui suit:

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

J'obtiens l'erreur suivante dans Python 3.x:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not int

... et une erreur similaire dans Python 2.x:

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

Comment puis-je contourner ce problème?

48
Zero Piraeus

Le problème ici est que l'opérateur + a (au moins) deux significations différentes en Python: pour les types numériques, cela signifie "additionne les nombres":

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

... et pour les types de séquence, cela signifie "concaténer les séquences":

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

En règle générale, Python ne convertit pas implicitement les objets d'un type à un autre1 afin de rendre les opérations "logiques", car cela serait source de confusion: par exemple, vous pourriez penser que '3' + 5 devrait signifier '35', mais quelqu'un d'autre pourrait penser que cela devrait signifier 8 ou même '8'.

De même, Python ne vous laissera pas concaténer deux types de séquence différents:

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

Pour cette raison, vous devez effectuer la conversion de manière explicite, que vous souhaitiez une concaténation ou une addition:

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

Cependant, il existe un meilleur moyen. Selon la version de Python que vous utilisez, il existe trois types de formatage de chaîne disponibles.2, ce qui vous permet non seulement d'éviter plusieurs opérations +:

>>> 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.'

... mais vous permettent également de contrôler l'affichage des valeurs:

>>> 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).'

Que vous utilisiez % interpolation , str.format() , ou f-strings c'est vous qui décidez:% interpolation dure depuis le plus longtemps (et est familier aux personnes ayant une formation en C), str.format() est souvent plus puissant, et les chaînes de caractères sont toujours plus puissantes (mais disponibles uniquement dans Python 3.6 et versions ultérieures).

Une autre alternative consiste à utiliser le fait que si vous donnez print plusieurs arguments de position, il joindra leurs représentations de chaîne à l'aide de l'argument de mot clé sep (dont la valeur par défaut est ' '):

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

... mais ce n'est généralement pas aussi flexible que d'utiliser les capacités de formatage de chaînes intégrées de Python.


1 Bien qu'il s'agisse d'une exception pour les types numériques, la plupart des gens s'accorderaient sur la «bonne» chose à faire:

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

2 En fait, quatre ... mais les chaînes de modèle sont rarement utilisées et quelque peu maladroites.

77
Zero Piraeus

TL; DR

  1. soit: print("You have " + str(things) + " things.") (l'ancienne. manière.école)

  2. ou: print("You have {} things.".format(things)) (le nouveau Pythonic et la manière recommandée)


Un peu plus d'explication verbale:
Bien que l'excellente réponse de @Zero Piraeus ci-dessus contienne quelque chose qui ne soit pas couvert, je vais essayer de le "réduire" un peu:
Vous ne pouvez pas concaténer une chaîne et un nombre (de quelque nature que ce soit) en python car ces objets ont des définitions différentes de l'opérateur plus (+) qui ne sont pas compatibles entre eux (Dans le cas str est utilisé + pour la concaténation, dans la casse numérique est utilisée pour additionner deux nombres) ... .. Donc, afin de résoudre ce "malentendu" entre objets:

  1. L'ancienne méthode consiste à convertir le nombre en chaîne avec la méthode str(anything), puis à concaténer le résultat avec une autre chaîne
  2. La méthode la plus recommandée et Pythonic consiste à utiliser la méthode format qui est très polyvalente (vous n’avez pas à prendre mon mot dessus, lisez la documentation et this article).

Amusez-vous bien et do lisez le @ Zero Piraeus, répondez-le, ça vaut vraiment le coup!

5
John Moutafis

Python 2.x

  1. 'You have %d things.' % things [ 1 ]
  2. 'You have {} things.'.format(things) [ 2 ]

Python 3.6+

  1. 'You have %d things.' % things [ 1 ]
  2. 'You have {} things.'.format(things) [ 2 ]
  3. f'You have {things} things.' [ 3 ]

Référence

  1. Formatage de chaîne de style printf
  2. Types intégrés -> str.format
  3. Littéraux de chaîne formatés
2
ngub05