Adloun

Écrire renommer cle(d, ancienne, nouvelle)

Exercice d'entraînement · niveau 2 · NSI (première), chapitre 5 — Les dictionnaires · Construire et modifier

Énoncé

Écrire renommer_cle(d, ancienne, nouvelle). Deux préconditions sont nécessaires — lesquelles, et que se passerait-il sans elles ?

Corrigé


def renommer_cle(d, ancienne, nouvelle):
    """Renomme une cle EN PLACE.

    Precondition : ancienne est presente, nouvelle est absente -- sinon on
                   ecraserait silencieusement une entree existante.
    """
    assert ancienne in d, "cle absente : " + str(ancienne)
    assert nouvelle not in d, "cle deja prise : " + str(nouvelle)
    d[nouvelle] = d.pop(ancienne)
    return d

Sans la première, d.pop(ancienne) lèverait KeyError — l'erreur arriverait quand même, mais sans dire laquelle des deux clés pose problème. Sans la seconde, le renommage détruirait l'entrée qui portait déjà le nouveau nom : le dictionnaire perdrait une entrée en silence, et len(d) diminuerait sans que rien ne le signale. C'est le défaut le plus grave des deux, parce qu'il ne produit aucune erreur.

pop plutôt que lire-puis-supprimer. d[nouvelle] = d.pop(ancienne) fait en une ligne ce que trois feraient : lire la valeur, l'installer sous le nouveau nom, effacer l'ancienne entrée. L'ordre compte — écrire del d[ancienne] avant d'avoir lu la valeur la perdrait.

Vérification.


d = {"lait": 1, "pain": 2}
assert renommer_cle(d, "lait", "lait demi-ecreme") == {"pain": 2,
                                                       "lait demi-ecreme": 1}
assert len(d) == 2

for cas in [("absente", "x"), ("pain", "pain")]:
    try:
        renommer_cle(dict(d), cas[0], cas[1])
        assert False, cas
    except AssertionError:
        pass

Le second cas — renommer "pain" en "pain" — est celui qu'on oublie de tester, et c'est celui qui détruirait l'entrée.

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.