868 votes

obtenir la clé en valeur dans le dictionnaire

J'ai créé une fonction qui recherche les âges dans le dictionnaire et affiche le nom correspondant:

 list = {'george':16,'amber':19}
search_age = raw_input("Provide age")
for age in list.values():
    if age == search_age:
        name = list[age]
        print name
 

Je sais comment comparer et trouver l'âge, je ne sais pas comment montrer le nom de la personne. De plus, je reçois un KeyError cause de la ligne 5. Je sais que ce n'est pas correct, mais je ne peux pas le faire en arrière.

Toute aide serait appréciée.

849voto

Stênio Elson Points 631
 mydict = {'george':16,'amber':19}
print mydict.keys()[mydict.values().index(16)] # Prints george
 

Ou en Python 3:

 print list(mydict.keys())[list(mydict.values()).index(16)] # Prints george
 

Fondamentalement, il sépare les valeurs du dictionnaire dans une liste, trouve la position de la valeur que vous avez et obtient la clé à cette position.

En savoir plus sur keys() et .values() dans Python 3: Python: moyen le plus simple d'obtenir la liste des valeurs de dict?

668voto

Cat Plus Plus Points 53385

Il n'y en a pas. dict n'est pas destiné à être utilisé de cette façon.

 for name, age in list.iteritems():
    if age == search_age:
        print name
 

317voto

agf Points 45052

Si vous souhaitez à la fois le nom et l'âge, vous devriez être en utilisant .items() qui vous donne la clé (key, value) n-uplets:

for name, age in mydict.items():
    if age == search_age:
        print name

Vous pouvez décompresser le tuple en deux variables distinctes droit dans l' for boucle, puis s'adapter à l'âge.

Vous devriez également envisager d'inverser le dictionnaire si vous êtes généralement va être à la recherche par âge, et pas deux personnes qui ont le même âge:

{16: 'george', 19: 'amber'}

ainsi, vous pouvez rechercher le nom d'un âge d'en faire juste

mydict[search_age]

J'ai été en l'appelant mydict au lieu de list car list est le nom d'un type, et vous ne devriez pas utiliser ce nom pour rien d'autre.

Vous pouvez même obtenir une liste de toutes les personnes avec un âge donné en une seule ligne:

[name for name, age in mydict.items() if age == search_age]

ou si il y a une seule personne à chaque âge:

next((name for name, age in mydict.items() if age == search_age), None)

qui va juste vous donner des None si il n'y a pas quelqu'un avec l'âge.

Enfin, si l' dict est longue et que vous êtes sur Python 2, vous devriez envisager d'utiliser .iteritems() au lieu de .items() comme Chat Plus en Plus dans sa réponse, car il n'a pas besoin de faire une copie de la liste.

100voto

Patrick Points 485

J'ai pensé qu'il serait intéressant de préciser les méthodes qui sont les plus rapides, et dans ce scénario:

Voici quelques tests, j'ai couru (sur un 2012 MacBook Pro)

>>> def method1(list,search_age):
...     for name,age in list.iteritems():
...             if age == search_age:
...                     return name
... 
>>> def method2(list,search_age):
...     return [name for name,age in list.iteritems() if age == search_age]
... 
>>> def method3(list,search_age):
...     return list.keys()[list.values().index(search_age)]

Les résultats de profile.run() sur chaque méthode 100000 fois:

Méthode 1:

>>> profile.run("for i in range(0,100000): method1(list,16)")
     200004 function calls in 1.173 seconds

Méthode 2:

>>> profile.run("for i in range(0,100000): method2(list,16)")
     200004 function calls in 1.222 seconds

Méthode 3:

>>> profile.run("for i in range(0,100000): method3(list,16)")
     400004 function calls in 2.125 seconds

Donc, cela montre que, pour un petit dict, la méthode 1 est la plus rapide. C'est probablement parce qu'elle renvoie le premier match, contrairement à tous les matchs comme méthode 2 (voir la note ci-dessous).


Il est intéressant de noter, d'effectuer les mêmes tests sur un dict que j'ai avec 2700 entrées, j'obtiens des résultats très différents (cette fois-run 10000 fois):

Méthode 1:

>>> profile.run("for i in range(0,10000): method1(UIC_CRS,'7088380')")
     20004 function calls in 2.928 seconds

Méthode 2:

>>> profile.run("for i in range(0,10000): method2(UIC_CRS,'7088380')")
     20004 function calls in 3.872 seconds

Méthode 3:

>>> profile.run("for i in range(0,10000): method3(UIC_CRS,'7088380')")
     40004 function calls in 1.176 seconds

Donc, ici, la méthode 3 est beaucoup plus rapide. Va juste pour montrer la taille de votre dict affectera la méthode que vous choisissez.

Notes: Méthode 2 renvoie une liste de tous les noms, alors que les méthodes 1 et 3 de retour seulement le premier match. Je n'ai pas considéré l'utilisation de la mémoire. Je ne suis pas sûr si la méthode 3 crée 2 autres listes (keys() et values()) et les stocke dans la mémoire.

35voto

faham Points 146
lKey = [key for key, value in lDictionary.iteritems() if value == lValue][0]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X