Aller au contenu

Anniversaires⚓︎

On dispose d'un dictionnaire Python dans lequel :

  • les clés sont les prénoms de différentes personnes. Il n'y a aucun prénom en double
  • les valeurs sont les mois de naissance de ces personnes stockées sous forme de nombres entiers (1 pour janvier, ... 12 pour décembre)

Par exemple :

🐍 Script Python
naissances = {'Nicolas': 10, 'Antoine': 7, 'Camille': 7}

Vous devez écrire une fonction anniversaires(naissances, mois) prenant en arguments le dictionnaire décrit ci-dessus ainsi qu'un numéro d'un mois et renvoyant une liste contenant les prénoms des personnes nées durant ce mois.

La liste renvoyée doit contenir les prénoms attendus dans un ordre quelconque.

Exemples
🐍 Console Python
>>> anniversaires({'Nicolas': 10, 'Antoine': 7, 'Camille': 7}, 1)
[]
>>> anniversaires({'Nicolas': 10, 'Antoine': 7, 'Camille': 7}, 10)
['Nicolas']
>>> anniversaires({'Nicolas': 10, 'Antoine': 7, 'Camille': 7}, 7)
['Antoine', Camille]
>>> anniversaires({'Nicolas': 10, 'Antoine': 7, 'Camille': 7}, 13)
[]
>>> anniversaires({}, 1)
[]
Tests sur les résultats triés

En Python, la comparaison de listes prend compte de l'ordre des éléments. Ainsi, les listes [0, 1] et [1, 0] diffèrent, quand bien même elles contiennent les mêmes valeurs.

Afin de s'assurer que la liste renvoyée par la fonction anniversaires contient bien les éléments attendus sans avoir à leur imposer un ordre, on compare donc la version triée du résultat à la valeur attendue. Ceci explique les tests sous la forme assert sorted(anniversaires(naissances, mois)) == résultat_attendu.

###
# testsbksl-nlassert sorted(anniversaires({"Nicolas": 10, "Antoine": 7, "Camille": 11}, 1)) == []bksl-nlassert sorted(anniversaires({"Nicolas": 10, "Antoine": 7, "Camille": 11}, 10)) == [bksl-nl "Nicolas"bksl-nl]bksl-nlassert sorted(anniversaires({"Nicolas": 10, "Antoine": 7, "Camille": 7}, 7)) == [bksl-nl "Antoine",bksl-nl "Camille",bksl-nl]bksl-nlassert sorted(anniversaires(dict(), 1)) == []bksl-nlassert sorted(anniversaires({"Nicolas": 10, "Antoine": 7, "Camille": 11}, 13)) == []bksl-nlbksl-nlbksl-nl# autres testsbksl-nl# Dictionnaire videbksl-nlassert sorted(anniversaires({}, 13)) == []bksl-nl# Tous nés le mois cherchébksl-nlassert sorted(anniversaires({"Nicolas": 1, "Antoine": 1, "Camille": 1}, 1)) == [bksl-nl "Antoine",bksl-nl "Camille",bksl-nl "Nicolas",bksl-nl]bksl-nl# Tous nés un mois non cherchébksl-nlassert sorted(anniversaires({"Nicolas": 1, "Antoine": 1, "Camille": 1}, 10)) == []bksl-nlbksl-nl 5/5

def anniversaires(naissances, mois):bksl-nl ...bksl-nlbksl-nlbksl-nl# Testsbksl-nlbksl-nlassert sorted(anniversaires(dict(), 1)) == []bksl-nlassert sorted(anniversaires({"Nicolas": 10, "Antoine": 7, "Camille": 11}, 1)) == []bksl-nlassert sorted(anniversaires({"Nicolas": 10, "Antoine": 7, "Camille": 11}, 10)) == [bksl-nl "Nicolas"bksl-nl]bksl-nlassert sorted(anniversaires({"Nicolas": 10, "Antoine": 7, "Camille": 7}, 7)) == [bksl-nl "Antoine",bksl-nl "Camille",bksl-nl]bksl-nlassert sorted(anniversaires({"Nicolas": 10, "Antoine": 7, "Camille": 11}, 13)) == []bksl-nlbksl-nldef anniversaires(naissances, mois):bksl-nl personnespy-undanniversaire = []bksl-nl for prenom in naissances:bksl-nl if naissances[prenom] == mois:bksl-nl personnespy-undanniversaire.append(prenom)bksl-nl return personnespy-undanniversairebksl-nlbksl-nl

A

Le problème revient à filtrer les clés d'un dictionnaire selon un critère portant sur les valeurs.

On présente ci-dessous différentes solutions parcourant le dictionnaire de façons différentes ainsi qu'une dernière méthode plus "fonctionnelle".

Explication de la solution⚓︎

On débute par la création d'une liste ayant vocation à contenir le prénom des personnes dont l'anniversaire tombe le mois passé en argument (ligne 2).

Ensuite on parcourt les clés du dictionnaire en faisant for prenom in naissances: (ligne 3). Celles-ci étant des prénoms de personnes, la variable parcourant ces clés est naturellement nommée prenom.

Pour chaque clé, on teste si la valeur associée (le mois de naissance) est égale au mois passé en argument (ligne 4). Si c'est le cas, on ajoute le prénom de la personne à la liste des résultats (ligne 5).

Enfin, on renvoie la liste des personnes dont l'anniversaire correspond.

Autres méthodes de parcours d'un dictionnaire⚓︎

Il est aussi possible de parcourir les clés d'un dictionnaire en faisant for prenom in naissances.keys():. Le reste du code ne change pas.

🐍 Script Python
def anniversaires(naissances, mois):
    personnes_anniversaire = []
    for prenom in naissances.keys():
        if naissances[prenom] == mois:
            personnes_anniversaire.append(prenom)
    return personnes_anniversaire

Enfin, une dernière méthode propre aux dictionnaires permet de parcourir directement les couples (cle, valeur). On fait alors for prenom, naissance in naissances.items():. Le test qui suit est alors plus lisible.

🐍 Script Python
def anniversaires(naissances, mois):
    personnes_anniversaire = []
    for prenom, mois_naissance in naissances.items():
        if mois_naissance == mois:
            personnes_anniversaire.append(prenom)
    return personnes_anniversaire

En une ligne !⚓︎

🐍 Script Python
def anniversaires(naissances, mois):
    return [prenom for prenom in naissances if naissances[prenom] == mois]

Dans cette méthode, on crée une liste par compréhension parcourant les couples (cle, valeur) comme dans la méthode précédente et testant immédiatement la validité du mois de naissance.

On rappelle que la concision d'un code n'est pas forcément signe de qualité ! On peut perdre en lisibilité.

Z