Participer au site avec un Tip
Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Proprement afficher vos collections

Manipulation de dictionnaires Dupliquer une collection Python


Accès rapide :
Présentation du module pprint
Utilisation de la fonction pprint
Utilisation de la classe PrettyPrinter

Présentation du module pprint

Le module pprint propose un mécanisme d'affichage plus agréable à lire pour vos collections (et plus généralement vos objets) complexes. En général, on parle de « Pretty Print » (d'où le nom du module).

Pour comprendre l'intérêt de ce module, considérons l'exemple de code suivant. Comme vous le constater, la collection principale (un dictionnaire) contient des valeurs étant elles-mêmes des collections (ici des listes). La principale question étant que pensez-vous de l'affichage sur la console ?

 1 
 2 
 3 
 4 
 5 
 6 
 7 
tasks = {
    date(2022, 3, 26): ["Apprendre Python", "Manger", "Dormir"],
    date(2022, 3, 27): ["Poursuivre l'apprentissage de Python", "..."],
    date(2022, 3, 28): ["Se reposer un peu", "Dormir"]
}

print(tasks)
Un exemple de dictionnaire qui contient des dates et des listes.

Et voici l'affichage produit par ce programme.

{datetime.date(2022, 3, 26): ['Apprendre Python', 'Manger', 'Dormir'], datetime.date(2022, 3, 27): ["Pou
rsuivre l'apprentissage de Python", '...'], datetime.date(2022, 3, 28): ['Se reposer un peu', 'Dormir']}

Clairement, il est difficile, au premier regard, de noter que la collection contient trois associations clé/valeur. De même, il n'est pas forcément facile de déterminer ou commence et se termine chaque liste. A comparer avec la définition de la collection dans le programme, on s'accordera à dire que c'est plus clair dans le code.

Le module pprint répond donc à ce besoin d'afficher proprement vos données. Il propose des fonctions et surtout la classe PrettyPrinter.

Utilisation de la fonction pprint

Commençons par un exemple simple : outre la donnée à afficher, nous ne passerons pas de paramètres supplémentaires à la fonction pprint.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
from pprint import pprint

tasks = {
    date(2022, 3, 26): ["Apprendre Python", "Manger", "Dormir"],
    date(2022, 3, 27): ["Poursuivre l'apprentissage de Python", "..."],
    date(2022, 3, 28): ["Se reposer un peu", "Dormir"]
}

pprint(tasks)
Utilisation de la fonction pprint.

Et voici l'affichage produit par ce programme. C'est déjà un peu mieux.

{datetime.date(2022, 3, 26): ['Apprendre Python', 'Manger', 'Dormir'],
 datetime.date(2022, 3, 27): ["Poursuivre l'apprentissage de Python", '...'],
 datetime.date(2022, 3, 28): ['Se reposer un peu', 'Dormir']}

La fonction pprint accepte un certain nombre de paramètres nommés. Voici la liste de ces paramètres ainsi que leurs significations.

Nom du paramètre Valeur par défaut Description
stream None Permet de spécifier le flux sur lequel produire l'affichage. Par défaut, sys.stdout.
indent 1 Permet de contrôler la taille de l'indentation utilisée pour l'affichage. Je préconise la valeur 4.
width 80 La taille maximale, en nombre de caractères, d'une ligne d'affichage.
depth None Permet de limiter en cas de collections imbriquées les unes dans les autres, le niveau maximal à afficher. Par défaut, tous les niveaux de collections sont affichés.
compact False Permet de demander d'afficher des collections de manière compacte quand plusieurs lignes sont requises.
sort_dicts True Permet d'indiquer, en cas d'affichage d'un dictionnaire, si les clés sont affichées dans l'ordre du dictionnaire ou triées (en utilisant l'opérateur <).
underscore_numbers False Permet d'indiquer si les grandes valeurs numériques doivent être présentées en utilisant le caractère de groupage de chiffres (le caractère _).

Testons quelques configurations.

>>> tasks = {
...     date(2022, 3, 26): ["Apprendre Python", "Manger", "Dormir"],
...     date(2022, 3, 27): ["Poursuivre l'apprentissage de Python", "...", "Allez se coucher pas trop tard"],
...     date(2022, 3, 28): ["Se reposer un peu", "Dormir"]
... }
>>> 
>>> pprint(tasks)
{datetime.date(2022, 3, 26): ['Apprendre Python', 'Manger', 'Dormir'],
 datetime.date(2022, 3, 27): ["Poursuivre l'apprentissage de Python",
                              '...',
                              'Allez se coucher pas trop tard'],
 datetime.date(2022, 3, 28): ['Se reposer un peu', 'Dormir']}
>>> 
>>> pprint(tasks, depth=1)
{datetime.date(2022, 3, 26): [...],
 datetime.date(2022, 3, 27): [...],
 datetime.date(2022, 3, 28): [...]}
>>> 
>>> pprint(tasks, indent=4)
{   datetime.date(2022, 3, 26): ['Apprendre Python', 'Manger', 'Dormir'],
    datetime.date(2022, 3, 27): [   "Poursuivre l'apprentissage de Python",
                                    '...',
                                    'Allez se coucher pas trop tard'],
    datetime.date(2022, 3, 28): ['Se reposer un peu', 'Dormir']}
>>> 
>>> pprint(tasks, indent=4, compact=True)
{   datetime.date(2022, 3, 26): ['Apprendre Python', 'Manger', 'Dormir'],
    datetime.date(2022, 3, 27): [   "Poursuivre l'apprentissage de Python",
                                    '...', 'Allez se coucher pas trop tard'],
    datetime.date(2022, 3, 28): ['Se reposer un peu', 'Dormir']}
>>>
Utilisation de quelques paramètres de la fonction pprint

Voici un autre exemple de code qui montre comment utiliser le caractère de groupage de chiffres.

>>> data = [value ** value for value in range(10)]
>>> pprint(data)
[1, 1, 4, 27, 256, 3125, 46656, 823543, 16777216, 387420489]
>>> pprint(data, underscore_numbers=True)
[1, 1, 4, 27, 256, 3_125, 46_656, 823_543, 16_777_216, 387_420_489]
>>>
>>> data = [value ** value for value in range(12)]
>>> data
[1, 1, 4, 27, 256, 3125, 46656, 823543, 16777216, 387420489, 10000000000, 285311670611]
>>> pprint(data)
[1,
 1,
 4,
 27,
 256,
 3125,
 46656,
 823543,
 16777216,
 387420489,
 10000000000,
 285311670611]
>>> pprint(data, underscore_numbers=True)
[1,
 1,
 4,
 27,
 256,
 3_125,
 46_656,
 823_543,
 16_777_216,
 387_420_489,
 10_000_000_000,
 285_311_670_611]
>>>
>>> pprint(data, underscore_numbers=True, compact=True)
[1, 1, 4, 27, 256, 3_125, 46_656, 823_543, 16_777_216, 387_420_489,
 10_000_000_000, 285_311_670_611] 
Utilisation du caractère de groupage de chiffres de la fonction pprint
la deuxième liste de l'exemple ci-dessus devenant trop grande (elle dépasse les 80 caractères), l'affichage produit par la fonction pprint force un retour à la ligne après chaque valeur de la liste. On peut annuler ce comportement en demandant un affichage plus compact (compact=True).

Mais une question vous a peut être traversé l'esprit : si l'on veut faire plusieurs appels à la fonction pprint avec les mêmes configurations, est-on obligé de répéter ces paramètres ? La réponse est non et vous avez même deux solutions pour y arriver : la première consiste à déballer un dictionnaire dans l'appel à la fonction et la seconde à utiliser la classe Pretty Printer.

Commençons par tester la première solution. Comme la fonction accepte un certain nombre de paramètres nommés, il est possible d'y déballer le contenu d'un dictionnaire lors de l'appel. Voici un exemple montrant cette possibilité.

>>> data1 = [value ** 5 for value in range(16)]
>>> data2 = [value ** 10 for value in range(16)]
>>> data3 = [value ** 15 for value in range(16)]
>>> 
>>> params = {
...     "underscore_numbers": True,
...     "compact": True,
...     "indent": 4
... }
>>> 
>>> pprint(data1, **params)
[   0, 1, 32, 243, 1_024, 3_125, 7_776, 16_807, 32_768, 59_049, 100_000,
    161_051, 248_832, 371_293, 537_824, 759_375]
>>> pprint(data2, **params)
[   0, 1, 1_024, 59_049, 1_048_576, 9_765_625, 60_466_176, 282_475_249,
    1_073_741_824, 3_486_784_401, 10_000_000_000, 25_937_424_601,
    61_917_364_224, 137_858_491_849, 289_254_654_976, 576_650_390_625]
>>> pprint(data3, **params)
[   0, 1, 32_768, 14_348_907, 1_073_741_824, 30_517_578_125, 470_184_984_576,
    4_747_561_509_943, 35_184_372_088_832, 205_891_132_094_649,
    1_000_000_000_000_000, 4_177_248_169_415_651, 15_407_021_574_586_368,
    51_185_893_014_090_757, 155_568_095_557_812_224, 437_893_890_380_859_375]
>>> 
On déballe un dictionnaire de paramètres lors des appels à la fonction pprint

Utilisation de la classe PrettyPrinter

Comme on venait de le préciser dans la section précédente, parfois on cherche à réaliser plusieurs affichages successifs avec la même configuration. Une seconde possibilité pour faire cela est d'utiliser une instance de la classe Pretty Printer.

Cette classe permet d'initialiser un « Printer » lors de sa construction. Ensuite, vous pouvez invoquer la méthode pprint sur votre instance de type Pretty Printer. Voici un exemple d'utilisation.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
from pprint import PrettyPrinter

data1 = [value ** 5 for value in range(16)]
data2 = [value ** 10 for value in range(16)]
data3 = [value ** 15 for value in range(16)]

printer = PrettyPrinter(indent=4, underscore_numbers=True, compact=True)

printer.pprint(data1)
printer.pprint(data2)
printer.pprint(data3)
Les résultats affichés seront les mêmes que dans l'exemple précédent.


Manipulation de dictionnaires Dupliquer une collection Python