Aller au contenu

Dictionnaire inversé⚓︎

Un dictionnaire associe des valeurs à des clés, comme par exemple {"Paris": "Tour Eiffel", "Rome": "Colisée", "Berlin": "Reichtag", "Londres": "Big Ben"} qui associe la valeur "Tour Eiffel" à la clé "Paris".

flowchart LR
  subgraph Clés
  P[Paris]
  R[Rome]
  B[Berlin] 
  L[Londres]
  end
  subgraph Valeurs
  TE(Tour Eiffel)
  BB(Big Ben)
  RE(Reichtag)
  CO(Colisée)
  end
  P --> TE
  R --> CO
  B --> RE
  L --> BB

On cherche dans cet exercice à « inverser » les dictionnaires c'est à dire à construire un dictionnaire dans lequel les associations sont dans l'autre sens. Dans le cas précédent on aurait :

flowchart LR
  subgraph Clés
  TE[Tour Eiffel]
  BB[Big Ben]
  RE[Reichtag]
  CO[Colisée]
  end
  subgraph Valeurs
  P(Paris)
  R(Rome)
  B(Berlin)
  L(Londres)
  end
  TE --> P
  CO --> R
  RE --> B
  BB --> L

Dans certains cas, l'inversion simple n'est pas possible. C'est le cas par exemple du dictionnaire {"Paris": "P", "Lyon": "L", "Nantes": "N", "Lille": "L"} puisque la valeur "L" est associée à la fois à la clé "Lyon" et à la clé "Lille".

flowchart LR
  subgraph Clés
  Ly[Lyon]
  Pa[Paris]
  Na[Nantes] 
  Li[Lille]
  end
  subgraph Valeurs
  P(P)
  L(L)
  N(N)
  end
  Ly --> L
  Pa --> P
  Na --> N
  Li --> L

On considère donc que le dictionnaire inverse associe à chaque valeur du dictionnaire initial la liste des clés associées.

Remarque

On ne demande pas à ce que ces listes soient triées dans un ordre particulier.

On triera le dictionnaire inverse dans les tests afin de gérer les différents résultats liés à des ordres différents. On garantit que toutes les clés et les valeurs utilisées sont de types comparables.

🐍 Script Python
def trier_valeurs(dico):
    for cle, valeur in dico.items():
        dico[cle] = sorted(valeur)
    return dico

Ainsi, le dictionnaire inverse de {"Paris": "Tour Eiffel", "Rome": "Colisée", "Berlin": "Reichtag", "Londres": "Big Ben"} est {'Tour Eiffel': ['Paris'], 'Colisée': ['Rome'], 'Reichtag': ['Berlin'], 'Big Ben': ['Londres']}.

Pour {"Paris": "P", "Lyon": "L", "Nantes": "N", "Lille": "L"} on peut obtenir {"P": ["Paris"], "L": ["Lyon", "Lille"], "N": ["Nantes"]}.

Vous devez écrire une fonction inverser de paramètre dico qui renvoie le dictionnaire inversé de dico.

Exemples

🐍 Console Python
>>> inverser({'a': 5, 'b': 7})
{5: ['a'], 7: ['b']}
>>> inverser({'a': 5, 'b': 7, 'c': 5})
{5: ['a', 'c'], 7: ['b']}
>>> inverser({"Paris": "Tour Eiffel", "Rome": "Colisée", "Berlin": "Reichtag", "Londres": "Big Ben"})
{'Tour Eiffel': ['Paris'], 'Colisée': ['Rome'], 'Reichtag': ['Berlin'], 'Big Ben': ['Londres']}
>>> inverser({"Paris": "P", "Lyon": "L", "Nantes": "N", "Lille": "L"})
{"P": ["Paris"], "L": ["Lyon", "Lille"], "N": ["Nantes"]}
# testsbksl-nldico = {"a": 5, "b": 7}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {5: ["a"], 7: ["b"]}bksl-nlbksl-nldico = {"a": 5, "b": 7, "c": 5}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {5: ["a", "c"], 7: ["b"]}bksl-nlbksl-nldico = {bksl-nl "Paris": "Tour Eiffel",bksl-nl "Rome": "Colisée",bksl-nl "Berlin": "Reichtag",bksl-nl "Londres": "Big Ben",bksl-nl}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {bksl-nl "Tour Eiffel": ["Paris"],bksl-nl "Colisée": ["Rome"],bksl-nl "Reichtag": ["Berlin"],bksl-nl "Big Ben": ["Londres"],bksl-nl}bksl-nlbksl-nldico = {"Paris": "P", "Lyon": "L", "Nantes": "N", "Lille": "L"}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {bksl-nl "P": ["Paris"],bksl-nl "L": ["Lille", "Lyon"],bksl-nl "N": ["Nantes"],bksl-nl}bksl-nlbksl-nl# autres testsbksl-nlbksl-nlassert inverser({}) == {}bksl-nlassert inverser({"a": "a"}) == {"a": ["a"]}bksl-nlassert trierpy-undvaleurs(inverser({1: 2, 2: 2, 3: 2})) == {2: [1, 2, 3]}bksl-nlbksl-nl ∞/∞

#--- HDR ---#bksl-nldef trierpy-undvaleurs(dico):bksl-nl for cle, valeur in dico.items():bksl-nl dico[cle] = sorted(valeur)bksl-nl return dicobksl-nlbksl-nlbksl-nl#--- HDR ---#bksl-nldef inverser(dico):bksl-nl ...bksl-nlbksl-nlbksl-nl# testsbksl-nldico = {"a": 5, "b": 7}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {5: ["a"], 7: ["b"]}bksl-nlbksl-nldico = {"a": 5, "b": 7, "c": 5}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {5: ["a", "c"], 7: ["b"]}bksl-nlbksl-nldico = {bksl-nl "Paris": "Tour Eiffel",bksl-nl "Rome": "Colisée",bksl-nl "Berlin": "Reichtag",bksl-nl "Londres": "Big Ben",bksl-nl}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {bksl-nl "Tour Eiffel": ["Paris"],bksl-nl "Colisée": ["Rome"],bksl-nl "Reichtag": ["Berlin"],bksl-nl "Big Ben": ["Londres"],bksl-nl}bksl-nlbksl-nldico = {"Paris": "P", "Lyon": "L", "Nantes": "N", "Lille": "L"}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {bksl-nl "P": ["Paris"],bksl-nl "L": ["Lille", "Lyon"],bksl-nl "N": ["Nantes"],bksl-nl}bksl-nlbksl-nl#--- HDR ---#bksl-nldef trierpy-undvaleurs(dico):bksl-nl for cle, valeur in dico.items():bksl-nl dico[cle] = sorted(valeur)bksl-nl return dicobksl-nlbksl-nlbksl-nl#--- HDR ---#bksl-nldef inverser(dico):bksl-nl dicopy-undinverse = {}bksl-nl for cle, valeur in dico.items():bksl-nl if valeur not in dicopy-undinverse:bksl-nl dicopy-undinverse[valeur] = [cle]bksl-nl else:bksl-nl dicopy-undinverse[valeur].append(cle)bksl-nl return dicopy-undinversebksl-nlbksl-nlbksl-nl# testsbksl-nldico = {"a": 5, "b": 7}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {5: ["a"], 7: ["b"]}bksl-nlbksl-nldico = {"a": 5, "b": 7, "c": 5}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {5: ["a", "c"], 7: ["b"]}bksl-nlbksl-nldico = {bksl-nl "Paris": "Tour Eiffel",bksl-nl "Rome": "Colisée",bksl-nl "Berlin": "Reichtag",bksl-nl "Londres": "Big Ben",bksl-nl}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {bksl-nl "Tour Eiffel": ["Paris"],bksl-nl "Colisée": ["Rome"],bksl-nl "Reichtag": ["Berlin"],bksl-nl "Big Ben": ["Londres"],bksl-nl}bksl-nlbksl-nldico = {"Paris": "P", "Lyon": "L", "Nantes": "N", "Lille": "L"}bksl-nlassert trierpy-undvaleurs(inverser(dico)) == {bksl-nl "P": ["Paris"],bksl-nl "L": ["Lille", "Lyon"],bksl-nl "N": ["Nantes"],bksl-nl}bksl-nlbksl-nl

A

Commentaires⚓︎

{{ IDE('exo_corr') }}

On peut parcourir le dictionnaire à l'aide de la méthode dico.items(). On récupère ainsi à chaque itération le couple cle, valeur.

Si valeur n'est pas présent parmi les clés de dico_inverse on crée une nouvelle entrée dans le dictionnaire.

Dans le cas contraire, on se contente d'ajouter cle à la liste dico_inverse[valeur].

Variante sans items()⚓︎

On peut aussi parcourir un dictionnaire avec for cle in dico:

Ici, le code deviendrait

🐍 Script Python
def inverser(dico):
    dico_inverse = {}
    for cle in dico:
        valeur = dico[cle]
        if valeur not in dico_inverse:
            dico_inverse[valeur] = [cle]
        else:
            dico_inverse[valeur].append(cle)
    return dico_inverse

Z

Retour en haut de la page