Adloun

Les types construits

Cours · NSI (première), chapitre 4 · première, spécialité numérique et sciences informatiques · le début du chapitre, la suite sur Adloun

Une liste : des valeurs rangées dans l'ordre, repérées par un indice qui commence à 0.

Les types vus jusqu'ici — entiers, flottants, booléens, chaînes — ont un point commun : une valeur, une donnée. Or les problèmes intéressants portent sur des collections : les notes d'une classe, les pixels d'une image, les coordonnées d'un point, les lignes d'un fichier. Il faut donc des types qui construisent de nouvelles valeurs à partir des valeurs de base. Le programme en présente trois, « au fur et à mesure qu'ils sont nécessaires » : les p-uplets, les tableaux, les dictionnaires. Ce chapitre traite les deux premiers ; le suivant est consacré aux dictionnaires.

Hors programme : Le vocabulaire de Python n'est pas celui de tout le monde

Le programme prévient : « en pratique, on utilise les appellations de Python, qui peuvent être différentes de celles d'autres langages ». Ce que ce chapitre appelle tableau s'écrit en Python avec le type list — le programme note d'ailleurs que « Python identifie listes et tableaux ». Dans d'autres langages, liste et tableau désignent deux structures très différentes, aux coûts opposés. Retenez la notion, pas seulement le mot.

4.1 Les p-uplets

4.1.1 Définition

Définition 4.1p-uplet

Un p-uplet (en anglais tuple) est une suite finie et ordonnée de valeurs, éventuellement de types différents. On le note entre parenthèses, les composantes séparées par des virgules.


point = (3, 7)                       # un couple d'entiers
eleve = ("Nour", 17, 15.5)           # un triplet : chaîne, entier, flottant

Deux traits le caractérisent, et les deux comptent :

iRemarque

Cette dernière propriété n'est pas une gêne, c'est une garantie. Un p-uplet sert à représenter une valeur composite dont les composantes forment un tout — des coordonnées, un résultat à deux volets — et qu'on remplace en bloc plutôt que par morceaux. Pour une collection qu'on veut modifier élément par élément, on emploie un tableau : c'est l'objet de la section suivante.

4.1.2 Renvoyer plusieurs valeurs à la fois

Capacité attendue

« Écrire une fonction renvoyant un p-uplet de valeurs. »

C'est l'usage principal du p-uplet. Une fonction ne renvoie qu'une seule valeur — mais si cette valeur est un p-uplet, elle en renvoie autant qu'on veut.


def division_euclidienne(a, b):
    """Quotient et reste de la division euclidienne de a par b.

    Précondition  : b > 0.
    Postcondition : a == b * q + r et 0 <= r < b.
    """
    assert b > 0, "le diviseur doit etre strictement positif"
    q = a // b
    r = a - b * q
    assert a == b * q + r and 0 <= r < b
    return q, r
AttentionLa précondition n'est pas décorative

On serait tenté d'écrire assert b != 0 : c'est insuffisant. Pour , la division entière de Python arrondit vers le bas et le reste devient négatif — la postcondition n'a alors plus de sens. Une précondition trop large laisse passer des appels que la fonction ne sait pas honorer. Exiger n'est pas une restriction arbitraire : c'est le domaine où la promesse tient.

Côté appelant, on récupère les composantes d'un coup — c'est l'affectation multiple, ou déballage :


q, r = division_euclidienne(17, 5)      # q vaut 3, r vaut 2

Méthode : Échanger deux variables

L'affectation multiple donne l'échange le plus court qui soit :


a, b = b, a

Le membre de droite est évalué entièrement avant la moindre affectation : c'est le p-uplet qui est construit, puis déballé. Aucune variable temporaire n'est nécessaire, et l'ordre n'a pas d'importance. Nous nous en servirons à chaque tri du chapitre 7.

4.1.3 Les p-uplets nommés

Le triplet ("Nour", 17, 15.5) pose un problème dès qu'il circule : rien ne dit ce que sont et . Un âge ? un rang ? une moyenne ? Il faut lire le code qui l'a produit pour le savoir — et ce code changera.

Définition 4.2p-uplet nommé, ou enregistrement

Un p-uplet nommé est un p-uplet dont chaque composante porte un nom de champ. On accède aux composantes par leur nom plutôt que par leur rang.


from collections import namedtuple

Eleve = namedtuple("Eleve", ["nom", "age", "moyenne"])
nour = Eleve("Nour", 17, 15.5)

nour.moyenne          # 15.5 — sans équivoque
nour[2]               # 15.5 également : un p-uplet nommé reste un p-uplet
Important

Le gain n'est pas cosmétique. nour.moyenne reste juste si l'on insère un champ au milieu ; nour[2] devient faux silencieusement. Nommer, c'est se protéger d'une classe entière d'erreurs — celles qui ne provoquent aucun message.

Exercices du chapitre

La suite du cours · Tous les exercices du chapitre