Adloun

Trois fonctions doublent les éléments d'un tableau

Exercice supplémentaire · niveau 3 (difficile) · NSI (première), chapitre 4 — Les types construits · Références partagées, copies et effets de bord

Énoncé

Trois fonctions doublent les éléments d'un tableau : l'une en place, l'une en renvoyant un nouveau tableau, la troisième les deux à la fois. Montrer que la troisième est un piège, et énoncer la convention à suivre.

Corrigé


def doubler_en_place(t):
    """Double chaque element de t EN PLACE. Ne renvoie rien."""
    for i in range(len(t)):
        t[i] = 2 * t[i]

def double_nouveau(t):
    """Renvoie un NOUVEAU tableau double, sans toucher a t."""
    return [2 * x for x in t]

Les deux sont honnêtes, et leur docstring suffit à savoir laquelle on tient :


u = [1, 2, 3] ; doubler_en_place(u) ; print(u)          # [2, 4, 6]
v = [1, 2, 3] ; w = double_nouveau(v) ; print(v, w)     # [1, 2, 3] [2, 4, 6]

La troisième, qui fait les deux :


def hybride(t):
    for i in range(len(t)):
        t[i] = 2 * t[i]
    return t                    # modifie ET renvoie

z = [1, 2, 3]
z2 = hybride(z)
z2[0] = 0
print(z)                        # [0, 4, 6]   <- z aussi !

z2 n'est pas un nouveau tableau : c'est z. L'appelant, voyant une valeur renvoyée, croit tenir un résultat indépendant et modifie sans précaution — et la modification atteint sa donnée d'origine.

La convention. Une fonction modifie son argument, ou bien elle renvoie une nouvelle valeur, jamais les deux. Deux indices reconnaissables :

Cette convention n'est pas un usage esthétique : c'est une partie de la spécification, au même titre que la précondition. Elle répond à la question « après l'appel, mes données ont-elles changé ? » — que la postcondition, seule, ne dit pas.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.