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.
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
>>> 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"]}
#--- 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
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