Exercices : révisions Python (fonctions et dictionnaires)

Exercice 1 : QCM

Pour chaque question, une seule réponse est correcte.

1. Que renvoie la fonction suivante pour mystere(3, 5) ?

def mystere(a, b=10):
    return a + b
  • A. 8
  • B. 13
  • C. 15
  • D. Une erreur

Correction publiée après la séance.

2. Quel est le résultat de ce code ?

x = 10
def g():
    x = 5
    return x
print(f"{g()} {x}")
  • A. 5 5
  • B. 5 10
  • C. 10 10
  • D. 10 5

Correction publiée après la séance.

3. Quelle est la complexité de la recherche d’une clé dans un dictionnaire Python ?

  • A. $O(n)$
  • B. $O(\log n)$
  • C. $O(1)$ en moyenne
  • D. $O(n^2)$

Correction publiée après la séance.

4. Que produit le code suivant ?

d = {'a': 1, 'b': 2, 'c': 3}
d['b'] = 5
d['d'] = 4
print(len(d))
  • A. 3
  • B. 4
  • C. 5
  • D. Une erreur

Correction publiée après la séance.


Exercice 2 : fonctions avec assertions et paramètres

a) Écrire une fonction moyenne(L) qui calcule la moyenne d’une liste de nombres. Ajouter une assertion vérifiant que la liste n’est pas vide et une docstring avec un exemple.

Indice

Commencer par assert len(L) > 0, "...", puis renvoyer la somme divisée par le nombre d’éléments. La docstring, entre """, dit ce que fait la fonction et donne un exemple d’appel avec son résultat.

b) Écrire une fonction saluer(prenom, formule="Bonjour") qui renvoie une chaîne de la forme "Bonjour Marie". Que renvoient les appels suivants ?

saluer("Alice")
saluer("Bob", "Salut")
saluer(formule="Bonsoir", prenom="Clara")
Indice

La fonction renvoie la formule, une espace, puis le prénom : une f-string suffit. Un paramètre absent de l’appel prend sa valeur par défaut, et des paramètres nommés peuvent être donnés dans n’importe quel ordre.

c) Écrire une fonction clamp(x, mini=0, maxi=100) qui renvoie x si mini <= x <= maxi, sinon mini ou maxi selon le cas. Ajouter une assertion vérifiant que mini <= maxi.

Indice

Après l’assertion, trois cas : x plus petit que mini, plus grand que maxi, ou entre les deux.

d) Écrire une fonction presentation(*args) qui accepte un nombre variable de prénoms et renvoie "Bonjour Alice, Bob et Clara" (avec une virgule entre les prénoms sauf avant le dernier, précédé de « et »).

Indice

args est le tuple des prénoms reçus. Avec un seul prénom, pas de « et ». Sinon, joindre tous les prénoms sauf le dernier avec ", ".join(args[:-1]), puis ajouter « et » et le dernier prénom.

Code à copier puis compléter
def presentation(*args):
    if len(args) == 0:
        return "Bonjour"
    if len(args) == 1:
        return f"Bonjour {args[0]}"
    debut = ", ".join(args[:-1])
    return f"Bonjour {...} et {...}"

Correction publiée après la séance.


Exercice 3 : dictionnaires – manipulation de base

On donne le dictionnaire suivant :

eleves = {
    "Alice": {"age": 17, "moyenne": 14.5},
    "Bob": {"age": 16, "moyenne": 12.0},
    "Clara": {"age": 17, "moyenne": 16.5},
    "David": {"age": 16, "moyenne": 9.5}
}

a) Écrire une fonction moyenne_classe(eleves) qui calcule la moyenne générale de la classe.

Indice

Parcourir les valeurs du dictionnaire : chacune est un dictionnaire, dont ["moyenne"] donne la moyenne de l’élève. Additionner ces moyennes, puis diviser par le nombre d’élèves, len(eleves).

b) Écrire une fonction meilleur_eleve(eleves) qui renvoie le nom de l’élève ayant la meilleure moyenne.

Indice

C’est une recherche de maximum sur les paires nom, infos de eleves.items() : garder le nom dont infos["moyenne"] est la plus grande rencontrée.

Code à copier puis compléter
def meilleur_eleve(eleves):
    meilleur = None
    meilleure_moy = -1
    for nom, infos in eleves.items():
        if infos["moyenne"] > ...:
            meilleure_moy = ...
            meilleur = ...
    return meilleur

c) Écrire une fonction eleves_par_age(eleves, age) qui renvoie la liste des noms des élèves ayant l’âge donné.

Indice

Parcourir les paires nom, infos et garder les noms dont infos["age"] vaut age.

d) Ajouter l’élève « Emma », 17 ans, moyenne 15.0 au dictionnaire et recalculer la moyenne de la classe.

Indice

On ajoute une clé à un dictionnaire par une affectation : eleves["Emma"] = {"age": 17, "moyenne": 15.0}. Appeler ensuite moyenne_classe(eleves).

Correction publiée après la séance.


Exercice 4 : compréhensions de dictionnaires

a) Créer par compréhension un dictionnaire associant à chaque entier de 1 à 10 son carré.

Indice

Une compréhension de dictionnaire s’écrit {cle: valeur for ... in ...} : ici la clé est l’entier et la valeur son carré, pour les entiers de range(1, 11).

b) À partir du dictionnaire {"a": 1, "b": 2, "c": 3, "d": 4}, créer par compréhension un nouveau dictionnaire ne contenant que les paires dont la valeur est paire.

Indice

Parcourir les paires avec .items() et ajouter la condition if v % 2 == 0 à la fin de la compréhension.

c) Écrire une fonction inverser(d) qui renvoie un dictionnaire où les clés et valeurs sont échangées. Que se passe-t-il si deux clés ont la même valeur ?

Indice

Pour chaque paire k, v, la nouvelle paire est v: k. Si deux clés ont la même valeur, la seconde affectation écrase la première : combien de paires reste-t-il ?

Correction publiée après la séance.


Exercice 5 : comptage et fréquences

a) Écrire une fonction compter_lettres(texte) qui renvoie un dictionnaire associant à chaque lettre (en minuscules) son nombre d’occurrences dans le texte.

Indice

Parcourir texte.lower() ; pour chaque lettre, repérée avec .isalpha(), ajouter 1 à son compteur s’il existe déjà, sinon le créer avec la valeur 1.

Code à copier puis compléter
def compter_lettres(texte):
    compteur = {}
    for car in texte.lower():
        if car.isalpha():
            if car in compteur:
                compteur[car] = ...
            else:
                compteur[car] = ...
    return compteur

b) Écrire une fonction lettre_frequente(texte) qui renvoie la lettre la plus fréquente.

Indice

Calculer d’abord le dictionnaire avec compter_lettres, puis chercher la clé de plus grande valeur, comme dans une recherche de maximum.

c) Écrire une fonction compter_mots(phrase) qui renvoie un dictionnaire associant à chaque mot son nombre d’occurrences.

Indice

phrase.split() donne la liste des mots ; le comptage se fait ensuite comme pour les lettres.

Correction publiée après la séance.


Exercice 6 : fonctions et dictionnaires combinés

a) Écrire une fonction statistiques(L) qui prend une liste de nombres et renvoie un dictionnaire contenant les clés "min", "max", "moyenne" et "nb_elements" avec les valeurs correspondantes.

Indice

Renvoyer un dictionnaire écrit en une seule fois : {"min": min(L), "max": ..., "moyenne": ..., "nb_elements": ...}.

b) Écrire une fonction fusionner(d1, d2) qui prend deux dictionnaires et renvoie un nouveau dictionnaire contenant toutes les paires clé-valeur des deux. Si une clé existe dans les deux, la valeur de d2 est conservée. Ne pas modifier d1 ni d2.

Indice

Créer un dictionnaire vide, y recopier toutes les paires de d1, puis toutes celles de d2, qui remplacent les valeurs des clés communes.

c) Écrire une fonction appliquer_remise(produits, remise=0.1) qui prend un dictionnaire {nom: prix} et renvoie un nouveau dictionnaire avec les prix réduits du pourcentage indiqué. La fonction ne doit pas modifier le dictionnaire original.

Indice

Construire un nouveau dictionnaire : pour chaque paire nom, prix, la valeur réduite est prix * (1 - remise).

Correction publiée après la séance.


Exercice 7 : synthèse – carnet de contacts

On souhaite créer un carnet de contacts sous forme de dictionnaire de dictionnaires.

a) Écrire une fonction ajouter_contact(carnet, nom, telephone, email="") qui ajoute un contact au carnet. Si le contact existe déjà, ses informations sont mises à jour.

Indice

Une seule affectation convient dans les deux cas : carnet[nom] = {"telephone": telephone, "email": email} crée le contact ou remplace ses informations.

b) Écrire une fonction rechercher(carnet, nom) qui renvoie les informations du contact ou un message indiquant qu’il n’existe pas (en utilisant .get()).

Indice

carnet.get(nom) renvoie la valeur associée à nom, ou None si la clé est absente : tester ce cas pour renvoyer le message.

c) Écrire une fonction supprimer_contact(carnet, nom) qui supprime un contact s’il existe, et affiche un message sinon.

Indice

Tester si nom in carnet : si oui, supprimer le contact avec del carnet[nom], sinon afficher le message avec print.

d) Écrire une fonction exporter(carnet) qui renvoie une liste de chaînes formatées "Nom : tel - email", triée par nom.

Indice

Parcourir sorted(carnet), qui donne les noms dans l’ordre alphabétique, et construire chaque chaîne avec une f-string à partir de carnet[nom].

e) Tester toutes ces fonctions avec un carnet contenant au moins quatre contacts.

Indice

Partir de carnet = {}, ajouter quatre contacts, puis appeler chaque fonction en affichant son résultat.

Correction publiée après la séance.