Écrire le maximum d'un tableau sans boucle explicite, dans le style…
Exercice supplémentaire · niveau 2 · NSI (première), chapitre 3 — Langages et programmation · Aux frontières du programme
Énoncé
Écrire le maximum d'un tableau sans boucle explicite, dans le style fonctionnel évoqué par le cours. Vérifier aussi que map et filter reproduisent exactement une compréhension. Que gagne-t-on, que perd-on ?
Corrigé
from functools import reduce
def maximum_reduce(t):
"""Plus grand element de t, sans boucle explicite.
Precondition : t est non vide.
"""
assert len(t) > 0
return reduce(lambda a, b: a if a > b else b, t)
for _ in range(2000):
t = [random.randint(-99, 99) for _ in range(random.randint(1, 12))]
assert maximum_reduce(t) == max(t)
Les tableaux aléatoires passent. reduce applique la fonction à deux arguments de proche en proche : elle « replie » le tableau en une seule valeur.
carres_pairs = [i * i for i in range(20) if i % 2 == 0]
autre = list(map(lambda i: i * i, filter(lambda i: i % 2 == 0, range(20))))
assert carres_pairs == autre
print(carres_pairs)
# [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
On retrouve exactement le tableau de la figure du chapitre 4 sur les compréhensions. filter est le filtre, map est l'expression : les trois parties de la compréhension, écrites séparément.
Ce qu'on gagne. Aucune variable modifiée, donc aucun état à suivre dans la trace : la correction se raisonne par composition. C'est la promesse du style fonctionnel présenté dans le cours, et l'ordinaire d'OCaml.
Ce qu'on perd. La lisibilité, ici. max(t) est plus clair que la version reduce, et la compréhension est plus claire que map(lambda ...). Python permet le style fonctionnel sans y être taillé. La leçon du chapitre reste la bonne : les langages ne diffèrent pas par leur puissance mais par leur commodité — et chaque style est commode pour ce à quoi il est destiné.
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.