Python >> Tutoriel Python >  >> Python

Formatage de chaîne Python :comment devenir un assistant de chaîne avec le mini-langage de spécification de format

Python fournit des options de formatage de chaîne fantastiques, mais que se passe-t-il si vous avez besoin d'un meilleur contrôle sur la façon dont les valeurs sont présentées ? C'est là qu'interviennent les spécificateurs de format.

Cet article commence par un bref aperçu des différentes approches de formatage de chaîne . Nous plongerons ensuite directement dans quelques exemples pour aiguiser votre appétit pour l'utilisation du mini-langage de spécification de format de Python dans vos propres projets.

Mais avant tout cela, jouons vous-même avec le formatage des chaînes dans le shell Python interactif :

Exercice :Créer une autre variable tax et calculez le montant de l'impôt à payer sur vos revenus (30%). Maintenant, ajoutez les deux valeurs income et tax dans la chaîne — en utilisant le spécificateur de format %s !

Ne vous inquiétez pas si vous avez du mal avec cet exercice. Après avoir lu ce tutoriel, vous ne le ferez pas! Apprenons tout ce que vous devez savoir pour commencer avec le formatage de chaînes en Python.

Options de formatage de chaîne

Les outils de formatage de chaîne de Python ont considérablement évolué au fil des ans.

L'approche la plus ancienne consiste à utiliser le % opérateur :

>>> number = 1 + 2
>>> 'The magic number is %s' % number
'The magic number is 3'


(L'extrait de code ci-dessus inclut déjà une sorte de spécificateur de format. Nous en reparlerons plus tard…)

Le str.format() méthode a ensuite été ajoutée :

>>> 'The magic number is {}'.format(number)
'The magic number is 3'

Plus récemment, les littéraux de chaîne formatés (également connus sous le nom de f-strings ) ont été présenté. Les F-strings sont plus faciles à utiliser et conduisent à un code plus propre, car leur syntaxe permet de placer la valeur d'une expression directement à l'intérieur d'une chaîne :

>>> f'The magic number is {number}'
'The magic number is 3'


D'autres options incluent la création de chaînes de modèle en important la classe Template à partir du module de chaîne de Python ou le formatage manuel des chaînes (que nous aborderons dans la section suivante).

Si tout cela est assez nouveau pour vous et que des détails supplémentaires seraient utiles avant de poursuivre, une explication approfondie des principales approches de formatage des chaînes peut être trouvée ici.

Spécificateurs de format

Après ce bref résumé, passons au véritable objectif de cet article :expliquer comment les spécificateurs de format peuvent vous aider à contrôler la présentation des valeurs dans les chaînes.

Les chaînes F sont l'approche la plus claire et la plus rapide pour le formatage des chaînes , je les utiliserai donc pour illustrer l'utilisation des spécificateurs de format dans le reste de cet article. Veuillez cependant garder à l'esprit que les spécificateurs peuvent également être utilisés avec le str.format() méthode. Aussi, les chaînes utilisant l'ancien % nécessite en fait une sorte de spécification de format - par exemple, dans le %s exemple montré dans la section précédente la lettre s est connu comme un type de conversion et indique que la représentation sous forme de chaîne standard de l'objet doit être utilisée.

Alors, que sont exactement les spécificateurs de format et quelles options offrent-ils ?

En termes simples, les spécificateurs de format vous permettent d'indiquer à Python comment vous souhaitez que les expressions intégrées dans les chaînes soient affichées.

Format de pourcentage et autres types

Par exemple, si vous souhaitez qu'une valeur soit affichée sous forme de pourcentage, vous pouvez le spécifier de la manière suivante :

>>> asia_population = 4_647_000_000
>>> world_population = 7_807_000_000
>>> percent = asia_population / world_population
>>> f'Proportion of global population living in Asia: {percent:.0%}'
'Proportion of global population living in Asia: 60%'


Que se passe-t-il ici ? Comment ce formatage a-t-il été réalisé ?

Eh bien, la première chose à noter est le deux-points : directement après le pourcentage variable intégré dans la f-string. Ces deux-points indiquent à Python que ce qui suit est un spécificateur de format qui doit être appliqué à la valeur de cette expression.

Le % Le symbole définit que la valeur doit être traitée comme un pourcentage, et le .0 indique le niveau de précision qui doit être utilisé pour l'afficher. Dans ce cas, le pourcentage a été arrondi à un nombre entier supérieur, mais si .1 avait été spécifié à la place, la valeur aurait été arrondie à une décimale et affichée sous la forme 59,5 % ; utiliser .2 aurait donné 59,52 % et ainsi de suite.

Si aucun spécificateur de format n'avait été inclus avec l'expression, la valeur aurait été affichée sous la forme 0,5952350454720123, ce qui est beaucoup trop précis !

(Le symbole % appliqué dans ce contexte ne doit pas être confondu avec l'opérateur % utilisé dans l'ancienne syntaxe de formatage de chaîne.)

Le pourcentage n'est que la pointe de l'iceberg en ce qui concerne les valeurs de type, il existe une gamme d'autres types qui peuvent être appliqués aux valeurs entières et flottantes.

Par exemple, vous pouvez afficher des entiers aux formats binaire, octal ou hexadécimal en utilisant respectivement les valeurs de type b, o et x :

>>> binary, octal, hexadecimal = [90, 90, 90]
>>> f'{binary:b} - {octal:o} - {hexadecimal:x}'
'1011010 - 132 - 5a'


Pour une liste complète des options, consultez le lien vers la zone pertinente de la documentation officielle de Python dans Autres lectures partie en fin d'article.

Format de largeur, alignement et remplissage

Une autre fonctionnalité pratique de spécification de format est la possibilité de définir la largeur minimale que les valeurs doivent occuper lorsqu'elles sont affichées dans des chaînes.

Pour illustrer comment cela fonctionne, si vous deviez imprimer les éléments de la liste ci-dessous dans des colonnes sans spécification de format, vous obtiendriez le résultat suivant :

>>> python, java, p_num, j_num = ["Python Users", "Java Users", 8.2, 7.5]
>>> print(f"|{python}|{java}|\n|{p_num}|{j_num}|")
|Python Users|Java Users|
|8.2|7.5|


Pas génial, mais avec l'inclusion de certaines valeurs de largeur, les choses commencent à s'améliorer :

>>> print(f"|{python:16}|{java:16}|\n|{p_num:16}|{j_num:16}|")
|Python Users    |Java Users      |
|             8.2|             7.5|


Comme vous pouvez le voir, la largeur est spécifiée en ajoutant un nombre après les deux-points.

La nouvelle sortie est meilleure, mais il semble un peu étrange que les titres soient alignés à gauche alors que les chiffres sont alignés à droite. Qu'est-ce qui pourrait en être la cause ?

Eh bien, c'est en fait lié à l'approche par défaut de Python pour différents types de données. Les valeurs de chaîne sont alignées à gauche par défaut, tandis que les valeurs numériques sont alignées à droite. (Cela peut sembler un peu étrange, mais c'est cohérent avec l'approche adoptée par Microsoft Excel et d'autres logiciels de tableur.)

Heureusement, vous n'avez pas à vous contenter des paramètres par défaut. Si vous souhaitez modifier ce comportement, vous pouvez utiliser l'une des options d'alignement. Par exemple, en se concentrant sur la première colonne uniquement maintenant par souci de simplicité, si nous voulons aligner le nombre à gauche, cela peut être fait en ajoutant le < symbole avant le p_num valeur de la largeur de la variable :

>>> print(f"|{python:16}|\n|{p_num:<16}|")
|Python Users    |
|8.2             |


Et l'inverse peut tout aussi bien être réalisé en ajoutant un > symbole devant le spécificateur de largeur associé à la valeur du titre :

>>> print(f"|{python:>16}|\n|{p_num:16}|")
|    Python Users|
|             8.2|


Mais que se passe-t-il si vous voulez que les lignes soient centrées ? Heureusement, Python vous couvre également sur ce front. Tout ce que vous avez à faire est d'utiliser le ^ symbole à la place :

>>> print(f"|{python:^16}|\n|{p_num:^16}|")
|  Python Users  |
|      8.2       |


Le caractère de remplissage par défaut de Python est un espace, et c'est ce qui a été utilisé jusqu'à présent lors de l'expansion de la largeur de nos valeurs. Nous pouvons cependant utiliser presque tous les personnages que nous aimons. Il suffit de le placer devant l'option d'alignement. Par exemple, voici à quoi ressemble la sortie lorsqu'un trait de soulignement est utilisé pour remplir l'espace supplémentaire dans la ligne de titre de notre colonne :

>>> print(f"|{python:_^16}|\n|{p_num:^16}|")
|__Python Users__|
|      8.2       |


Il convient de noter que la même sortie peut être obtenue manuellement en utilisant le str() fonction avec la méthode de chaîne appropriée (dans ce cas str.center() ):

>>> print("|", python.center(16, "_"), "|\n|", str(p_num).center(16), "|", sep="")
|__Python Users__|
|      8.2       |


Mais l'approche f-string est beaucoup plus succincte et considérablement plus rapide à évaluer au moment de l'exécution.

Bien sûr, la sortie de données formatées en lignes et en colonnes n'est qu'un exemple de la façon dont la spécification de la largeur, de l'alignement et des caractères de remplissage peut être utilisée.

De plus, en réalité, si vous cherchez à produire un tableau d'informations, vous n'utiliserez probablement pas un seul print() déclaration. Vous aurez probablement plusieurs lignes et colonnes à afficher, qui peuvent être construites avec une boucle ou une compréhension, peut-être en utilisant str.join() pour insérer des séparateurs etc.

Cependant, quelle que soit l'application, dans la plupart des cas, l'utilisation de chaînes f avec des spécificateurs de format au lieu d'adopter une approche manuelle se traduira par un code plus lisible et plus efficace.

Affichage de l'horloge sur 24 heures

Comme autre exemple, disons que nous voulons calculer quelle sera l'heure de la journée après qu'un certain nombre d'heures et de minutes se seront écoulées (à partir de minuit) :

>>> hours = 54
>>> minutes = 128
>>> quotient, minute = divmod(minutes, 60)
>>> hour = (hours + quotient) % 24
>>> f'{hour}:{minute}'
'8:8'


Jusqu'ici tout va bien. Notre programme nous dit correctement qu'après 54 heures et 128 minutes, l'heure de la journée sera 8 heures du matin 8 minutes, mais le problème est que ce n'est pas très facile à lire. Une confusion pourrait survenir quant à savoir s'il est réellement 8 heures du matin ou du soir et avoir un seul chiffre pour représenter le nombre de minutes semble tout simplement étrange.

Pour résoudre ce problème, nous devons insérer des zéros non significatifs lorsque la valeur de l'heure ou de la minute est un chiffre unique, ce qui peut être réalisé en utilisant quelque chose appelé remplissage par zéro sensible aux signes. Cela semble assez compliqué, mais en substance, nous avons juste besoin d'utiliser un 0 au lieu de l'une des valeurs d'alignement que nous avons vues précédemment lors de la définition de la chaîne f, avec une valeur de largeur de 2 :

>>> f'{hour:02}:{minute:02}'
'08:08'


Hé hop ! L'heure est maintenant dans un format clair de 24 heures. Cette approche fonctionnera également parfaitement pour les heures avec des heures et des minutes à deux chiffres, car la valeur de la largeur est maximale et le remplissage par zéro ne sera pas utilisé si la valeur de l'une ou l'autre des expressions occupe tout l'espace :

>>> hours = 47
>>> minutes = 59
...
>>> f'{hour:02}:{minute:02}'
'23:59'

Options de regroupement

Plus les nombres sont longs, plus ils peuvent être difficiles à lire sans séparateurs de milliers, et si vous devez les insérer, cela peut être fait en utilisant une option de regroupement :

>>> proxima_centauri = 40208000000000
>>> f'The closest star to our own is {proxima_centauri:,} km away.'
'The closest star to our own is 40,208,000,000,000 km away.'


Vous pouvez également utiliser un trait de soulignement comme séparateur si vous préférez :

>>> f'The closest star to our own is {proxima_centauri:_} km away.'
'The closest star to our own is 40_208_000_000_000 km away.'


Tout mettre ensemble

Vous n'aurez probablement pas besoin d'utiliser une grande variété de valeurs de spécification de format avec une seule expression aussi souvent, mais si vous voulez en assembler plusieurs, l'ordre est important.

Pour rester dans le thème astronomique, à des fins de démonstration, nous allons maintenant montrer la distance entre le Soleil et Neptune en millions de kilomètres :

>>> neptune = "Neptune"
>>> n_dist = 4_498_252_900 / 1_000_000
>>> print(f"|{neptune:^15}|\n|{n_dist:~^15,.1f}|")
|    Neptune    |
|~~~~4,498.3~~~~|


Comme vous pouvez le voir, en lisant de droite à gauche, nous devons placer les valeurs de spécification du format n_dist dans l'ordre suivant :

  1. Tapez – f définit que la valeur doit être affichée en notation à virgule fixe
  2. Précision – .1 indique qu'une seule décimale doit être utilisée 
  3. Regroupement – , indique qu'une virgule doit être utilisée comme séparateur de milliers
  4. Largeur – 15 est défini comme le nombre minimum de caractères
  5. Aligner – ^ définit que la valeur doit être centrée
  6. Remplir – ~ indique qu'un tilde doit occuper tout espace inutilisé

En général, les valeurs de format qui ne sont pas requises peuvent simplement être omises. Cependant, si une valeur de remplissage est spécifiée sans option d'alignement correspondante, une ValueError sera levée.

Réflexions finales et lectures complémentaires

Les exemples présentés dans cet article ont été considérablement simplifiés pour démontrer les fonctionnalités de manière simple, mais j'espère qu'ils ont donné matière à réflexion, vous permettant d'envisager des façons d'appliquer le mini-langage de spécification de format dans des projets du monde réel.

Des colonnes de base ont été utilisées pour illustrer des aspects de la spécification de format, et l'affichage d'informations tabulaires dans le cadre d'une application de ligne de commande est un exemple de la manière dont ce type de formatage pourrait être utilisé.

Si vous souhaitez utiliser et afficher de plus grands volumes de données sous forme de tableau, vous feriez bien de consulter les excellents outils fournis par la bibliothèque pandas, que vous pouvez lire dans ces articles Finxter.

De plus, si vous souhaitez voir la liste complète des valeurs de spécification de format disponibles, vous pouvez les trouver dans cette section de la documentation officielle de Python.

La meilleure façon de vraiment comprendre le fonctionnement des spécificateurs de format est de les expérimenter vous-même. Essayez-le - je suis sûr que vous vous amuserez en cours de route !