Obtenir la clé en valeur dans le dictionnaire

j'ai créé une fonction qui va chercher des âges dans un Dictionary et afficher le nom correspondant:

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

je sais comparer et trouver l'âge Je ne sais juste 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 sais pas comment le faire chercher à l'envers.

399
demandé sur Lonely Neuron 2011-11-06 01:09:18

30 réponses

il n'y en a pas. dict ne doit pas être utilisé de cette façon.

for name, age in dictionary.items():    # for name, age in dictionary.iteritems():  (for Python 2.x)
    if age == search_age:
        print(name)
362
répondu Cat Plus Plus 2018-09-09 13:22:17
mydict = {'george':16,'amber':19}
print mydict.keys()[mydict.values().index(16)] # Prints george

ou en Python 3.x:

mydict = {'george':16,'amber':19}
print(list(mydict.keys())[list(mydict.values()).index(16)]) # Prints george

essentiellement, 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.

plus d'informations sur keys() et .values() en Python 3: Python: la manière la plus simple d'obtenir une liste de valeurs à partir de dict?

407
répondu Stênio Elson 2017-05-23 12:02:56

si vous voulez à la fois le nom et l'âge, vous devez utiliser .items() qui vous donne la clé (key, value) tuples:

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

vous pouvez défaire le tuple en deux variables séparées dans la boucle for , puis faire correspondre l'âge.

vous devriez également envisager d'inverser le dictionnaire si vous allez généralement chercher par l'âge, et aucune deux personnes ont le même âge:

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

donc vous pouvez rechercher le nom d'un âge en faisant juste

mydict[search_age]

Je l'ai appelé mydict au lieu de list parce que list est le nom d'un type intégré, et vous ne devriez pas utiliser ce nom pour autre chose.

vous pouvez même obtenir une liste de tous les gens avec un âge donné dans une ligne:

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

ou s'il n'y a qu'une personne par âge:

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

qui vous donnera juste None s'il n'y a personne de cet âge.

enfin, si le dict est long et que vous êtes sur Python 2, vous devriez envisager d'utiliser .iteritems() au lieu de .items() comme Cat Plus L'a fait dans sa réponse, car il n'a pas besoin de faire une copie de la liste.

191
répondu agf 2011-11-05 21:18:42

j'ai pensé qu'il serait intéressant de souligner quelles méthodes sont les plus rapides, et dans quel 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)]

résultats de profile.run() pour 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 dicton, la méthode 1 est la plus rapide. C'est très probablement parce qu'il renvoie la première correspondance, par opposition à toutes les correspondances comme la méthode 2 (Voir note ci-dessous).


fait intéressant, en effectuant les mêmes tests sur un dict que j'ai avec 2700 entrées, j'obtiens des résultats tout à fait différents (cette fois, courir 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: La méthode 2 retourne une liste de tous les noms, tandis que les méthodes 1 et 3 ne renvoient que la première correspondance. Je n'ai pas considéré l'utilisation de la mémoire. Je ne suis pas sûr que la méthode 3 crée 2 listes supplémentaires (keys() et values()) et les stocke en mémoire.

55
répondu Patrick 2013-01-31 11:42:59

une version en ligne de: (i est un vieux dictionnaire, p est un dictionnaire inversé)

explication: I. keys() et I. values () retourne deux listes avec les clés et les valeurs du dictionnaire respectivement. La fonction zip permet d'assembler des listes pour produire un dictionnaire.

avertissement: cela ne fonctionnerait que si les valeurs sont hachables et uniques.

p = dict(zip(i.values(),i.keys()))
34
répondu fanny 2018-06-27 12:15:36
a = {'a':1,'b':2,'c':3}
{v:k for k, v in a.items()}[1]

ou mieux

{k:v for k, v in a.items() if v == 1}
20
répondu Jelen 2017-04-21 13:00:17
lKey = [key for key, value in lDictionary.iteritems() if value == lValue][0]
18
répondu faham 2012-07-11 00:35:40

Voici mon point de vue sur ce problème. :) Je viens de commencer à apprendre le Python, alors je l'appelle:

"Les Compréhensible pour les débutants" solution.

#Code without comments.

list1 = {'george':16,'amber':19, 'Garry':19}
search_age = raw_input("Provide age: ")
print
search_age = int(search_age)

listByAge = {}

for name, age in list1.items():
    if age == search_age:
        age = str(age)
        results = name + " " +age
        print results

        age2 = int(age)
        listByAge[name] = listByAge.get(name,0)+age2

print
print listByAge

.

#Code with comments.
#I've added another name with the same age to the list.
list1 = {'george':16,'amber':19, 'Garry':19}
#Original code.
search_age = raw_input("Provide age: ")
print
#Because raw_input gives a string, we need to convert it to int,
#so we can search the dictionary list with it.
search_age = int(search_age)

#Here we define another empty dictionary, to store the results in a more 
#permanent way.
listByAge = {}

#We use double variable iteration, so we get both the name and age 
#on each run of the loop.
for name, age in list1.items():
    #Here we check if the User Defined age = the age parameter 
    #for this run of the loop.
    if age == search_age:
        #Here we convert Age back to string, because we will concatenate it 
        #with the person's name. 
        age = str(age)
        #Here we concatenate.
        results = name + " " +age
        #If you want just the names and ages displayed you can delete
        #the code after "print results". If you want them stored, don't...
        print results

        #Here we create a second variable that uses the value of
        #the age for the current person in the list.
        #For example if "Anna" is "10", age2 = 10,
        #integer value which we can use in addition.
        age2 = int(age)
        #Here we use the method that checks or creates values in dictionaries.
        #We create a new entry for each name that matches the User Defined Age
        #with default value of 0, and then we add the value from age2.
        listByAge[name] = listByAge.get(name,0)+age2

#Here we print the new dictionary with the users with User Defined Age.
print
print listByAge

.

#Results
Running: *\test.py (Thu Jun 06 05:10:02 2013)

Provide age: 19

amber 19
Garry 19

{'amber': 19, 'Garry': 19}

Execution Successful!
9
répondu Deithrian 2013-06-06 02:26:36

vous pouvez obtenir la clé en utilisant dict.keys() , dict.values() et list.index() méthodes, voir exemples de code ci-dessous:

names_dict = {'george':16,'amber':19}
search_age = int(raw_input("Provide age"))
key = names_dict.keys()[names_dict.values().index(search_age)]
8
répondu Andriy Ivaneyko 2016-11-23 11:23:24

si vous voulez trouver la clé par la valeur, vous pouvez utiliser une compréhension de dictionnaire pour créer un dictionnaire de recherche et puis utiliser cela pour trouver la clé à partir de la valeur.

lookup = {value: key for key, value in self.data}
lookup[value]
6
répondu Safia Abdalla 2014-12-18 18:37:30

envisagez D'utiliser Pandas. Comme indiqué dans "Python for Data Analysis "de William McKinney 151950920"

une autre façon de penser une série est comme une longueur fixe, ordonnée dict, que c'est une cartographie des valeurs de l'indice de valeurs de données. Il peut être utilisée dans de nombreux contextes où vous pourriez utiliser un dict.

import pandas as pd
list = {'george':16,'amber':19}
lookup_list = pd.Series(list)

pour interroger votre Série faire ce qui suit:

lookup_list[lookup_list.values == 19]

ce Qui donne:

Out[1]: 
amber    19
dtype: int64

si vous avez besoin de faire quoi que ce soit d'autre avec la réponse dans une liste pourrait être utile:

answer = lookup_list[lookup_list.values == 19].index
answer = pd.Index.tolist(answer)
6
répondu Axel 2017-08-18 17:19:49

ici, recover_key prend le dictionnaire et la valeur pour trouver dans le dictionnaire. Nous faisons alors une boucle sur les touches dans le dictionnaire et faisons une comparaison avec celle de la valeur et retournons cette touche particulière.

def recover_key(dicty,value):
    for a_key in dicty.keys():
        if (dicty[a_key] == value):
            return a_key
5
répondu shishir 2017-11-25 20:02:08
for name in mydict.keys():
    if mydict[name] == search_age:
        print name 
        #or do something else with it. 
        #if in a function append to a temporary list, 
        #then after the loop return the list
4
répondu patrick 2012-09-21 15:31:41

il est répondu, mais il pourrait être fait avec une fantaisie "carte / réduire" l'utilisation, par exemple:

def find_key(value, dictionary):
    return reduce(lambda x, y: x if x is not None else y,
                  map(lambda x: x[0] if x[1] == value else None, 
                      dictionary.iteritems()))
4
répondu formiaczek 2013-05-31 09:21:51
def get_Value(dic,value):
    for name in dic:
        if dic[name] == value:
            del dic[name]
            return name
4
répondu Raj Damani 2016-03-07 06:41:10
get_key = lambda v, d: next(k for k in d if d[k] is v)
4
répondu Brett 2017-11-26 06:44:56

voici mon point de vue. C'est bon pour afficher des résultats multiples juste au cas où vous en auriez besoin. J'ai donc ajouté la liste

myList = {'george':16,'amber':19, 'rachel':19, 
           'david':15 }                         #Setting the dictionary
result=[]                                       #Making ready of the result list
search_age = int(input('Enter age '))

for keywords in myList.keys():
    if myList[keywords] ==search_age:
    result.append(keywords)                    #This part, we are making list of results

for res in result:                             #We are now printing the results
    print(res)

Et c'est tout...

3
répondu user3649211 2014-05-18 08:34:29

Il n'est pas facile de trouver une clé dans une liste par "recherche" de la valeur. Toutefois, si vous savez la valeur, itérer sur les touches, vous pouvez rechercher des valeurs dans le dictionnaire de l'élément. Si D [element] où D est un objet du dictionnaire, est égal à la clé que vous cherchez, vous pouvez exécuter du code.

D = {'Ali': 20, 'Marina': 12, 'George':16}
age = int(input('enter age:\t'))  
for element in D.keys():
    if D[element] == age:
        print(element)
3
répondu Ethan 2015-04-13 18:44:33

je sais que c'est vieux mais vous pourriez très facilement trouver toutes les personnes dans la liste avec votre âge de recherche en utilisant la compréhension de liste.

ages = {'george':16,'amber':19}
search = 16
print([name for (name, age) in ages.items() if age == search])
3
répondu fr1eza 2017-07-02 12:59:21

j'espère que cela pourrait aider...

for key in list:
   if list[key] == search_value:
       return key
3
répondu Nat 2017-07-07 14:00:33

j'ai trouvé cette réponse très efficace mais pas très facile à lire pour moi.

Pour le rendre plus clair, vous pouvez inverser la clé et la valeur d'un dictionnaire. C'est faire les valeurs de clés et les clés de valeurs, comme vu ici .

mydict = {'george':16,'amber':19}
res = dict((v,k) for k,v in mydict.iteritems())
print(res[16]) # Prints george

ou

mydict = {'george':16,'amber':19}
dict((v,k) for k,v in mydict.iteritems())[16]

qui est essentiellement le même que cet autre réponse .

3
répondu Rafael Valero 2018-05-08 11:50:43

essayez cette doublure pour inverser un dictionnaire:

reversed_dictionary = dict(map(reversed, dictionary.items()))
3
répondu johnaphun 2018-08-05 19:20:22

Chat Plus en Plus mentionné que ce n'est pas un dictionnaire est destiné à être utilisé. Voici pourquoi:

La définition d'un dictionnaire est analogue à celle d'une cartographie en mathématiques. Dans ce cas, un dict est une correspondance de K (l'ensemble des clés) à V (les valeurs) - mais pas l'inverse. Si vous déréférencer un dict, vous vous attendez à obtenir exactement une valeur renvoyée. Mais, il est parfaitement légal pour des touches différentes de mapper sur la même valeur, par exemple:

d = { k1 : v1, k2 : v2, k3 : v1}

quand vous regardez une clé par sa valeur correspondante, vous inversez essentiellement le dictionnaire. Mais une cartographie n'est pas nécessairement inversible! Dans cet exemple, demander la clé correspondant à v1 pourrait donner k1 ou k3. Devriez-vous retourner? Juste le premier trouvé? C'est pourquoi indexof() n'est pas défini pour les dictionnaires.

si vous connaissez vos données, vous pouvez le faire. Mais une API ne peut pas supposer qu'un dictionnaire arbitraire est inversible, d'où l'absence d'un tel opération.

2
répondu Dan Ahlquist 2014-03-27 21:38:21

parfois int () peut être nécessaire:

titleDic = {'Фильмы':1, 'Музыка':2}

def categoryTitleForNumber(self, num):
    search_title = ''
    for title, titleNum in self.titleDic.items():
        if int(titleNum) == int(num):
            search_title = title
    return search_title
2
répondu wzbozon 2014-08-24 18:13:12

vous devez utiliser un dictionnaire et l'inverse de ce dictionnaire. Cela signifie que vous avez besoin d'une autre structure de données. Si vous êtes en python 3, Utilisez le module enum mais si vous utilisez python 2.7 utilisez enum34 qui est rétroporté pour python 2.

exemple:

from enum import Enum

class Color(Enum): 
    red = 1 
    green = 2 
    blue = 3

>>> print(Color.red) 
Color.red

>>> print(repr(Color.red)) 
<color.red: 1=""> 

>>> type(Color.red) 
<enum 'color'=""> 
>>> isinstance(Color.green, Color) 
True 

>>> member = Color.red 
>>> member.name 
'red' 
>>> member.value 
1 
2
répondu Hamid FzM 2015-09-06 17:54:20

a déjà été répondu, mais puisque plusieurs personnes ont mentionné inverser le dictionnaire, voici comment vous le faites dans une ligne (en supposant 1:1 cartographie) et quelques données perf divers:

python 2.6:

reversedict = dict([(value, key) for key, value in mydict.iteritems()])

2.7+:

reversedict = {value:key for key, value in mydict.iteritems()}

si vous pensez qu'il n'est pas 1:1, vous pouvez encore créer une cartographie inversée raisonnable avec un couple de lignes:

reversedict = defaultdict(list)
[reversedict[value].append(key) for key, value in mydict.iteritems()]

comme c'est lent: plus lent qu'une simple recherche, mais pas aussi lentement qu'on pourrait le penser - sur un dictionnaire 'droit' 100000 entrée, une recherche 'rapide' (c.-à-d. à la recherche d'une valeur qui devrait être tôt dans les touches) était environ 10x plus rapide que l'inversion du dictionnaire entier, et une recherche 'lente' (vers la fin) environ 4-5x plus rapide. Donc après au plus une dizaine de recherches, c'est payé pour lui-même.

la seconde version (avec Listes par item) prend environ 2,5 x aussi longtemps que la version simple.

largedict = dict((x,x) for x in range(100000))

# Should be slow, has to search 90000 entries before it finds it
In [26]: %timeit largedict.keys()[largedict.values().index(90000)]
100 loops, best of 3: 4.81 ms per loop

# Should be fast, has to only search 9 entries to find it. 
In [27]: %timeit largedict.keys()[largedict.values().index(9)]
100 loops, best of 3: 2.94 ms per loop

# How about using iterkeys() instead of keys()?
# These are faster, because you don't have to create the entire keys array.
# You DO have to create the entire values array - more on that later.

In [31]: %timeit islice(largedict.iterkeys(), largedict.values().index(90000))
100 loops, best of 3: 3.38 ms per loop

In [32]: %timeit islice(largedict.iterkeys(), largedict.values().index(9))
1000 loops, best of 3: 1.48 ms per loop

In [24]: %timeit reversedict = dict([(value, key) for key, value in largedict.iteritems()])
10 loops, best of 3: 22.9 ms per loop

In [23]: %%timeit
....: reversedict = defaultdict(list)
....: [reversedict[value].append(key) for key, value in largedict.iteritems()]
....:
10 loops, best of 3: 53.6 ms per loop

avait également quelques résultats intéressants avec ifilter. Théoriquement, ifilter devrait être plus rapide, en ce sens que nous pouvons utiliser itervalues () et peut-être ne pas avoir à créer/parcourir la liste de valeurs entière. Dans la pratique, les résultats ont été... bizarre...

In [72]: %%timeit
....: myf = ifilter(lambda x: x[1] == 90000, largedict.iteritems())
....: myf.next()[0]
....:
100 loops, best of 3: 15.1 ms per loop

In [73]: %%timeit
....: myf = ifilter(lambda x: x[1] == 9, largedict.iteritems())
....: myf.next()[0]
....:
100000 loops, best of 3: 2.36 us per loop

donc, pour les petits offsets, il était beaucoup plus rapide que n'importe quelle version précédente (2,36 *u*S contre un minimum de 1,48 *m*s pour les cas précédents). Cependant, pour les grands décalages près de la fin de la liste, il était beaucoup plus lent (15,1 ms vs. 1.48 mS). Les petites économies au bas de l'échelle ne valent pas le coût au haut de l'échelle, imho.

1
répondu Corley Brigman 2013-10-03 18:52:29
d= {'george':16,'amber':19}

dict((v,k) for k,v in d.items()).get(16)

la sortie est la suivante:

-> prints george
1
répondu Jeroen 2014-08-24 18:20:27

Voici comment vous accédez au dictionnaire pour faire ce que vous voulez:

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

bien sûr, vos noms sont si flous qu'on dirait qu'il imprime un âge, mais il imprime le nom. Puisque vous accédez par nom, cela devient plus compréhensible si vous écrivez:

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

mieux encore:

people = {'george': {'age': 16}, 'amber': {'age': 19}}
search_age = raw_input("Provide age")
for name in people:
    if people[name]['age'] == search_age:
        print name
1
répondu Surest Texas 2015-07-01 23:16:32

Voici une solution qui fonctionne à la fois en Python 2 et en Python 3:

dict((v, k) for k, v in list.items())[search_age]

la partie jusqu'à [search_age] construit le dictionnaire inverse (où les valeurs sont des clés et vice-versa). Vous pouvez créer une méthode helper qui cache ce dictionnaire inversé comme ceci:

def find_name(age, _rev_lookup=dict((v, k) for k, v in ages_by_name.items())):
    return _rev_lookup[age]

ou plus généralement une usine qui créerait une méthode de recherche de noms par âge pour une ou plusieurs de vos listes

def create_name_finder(ages_by_name):
    names_by_age = dict((v, k) for k, v in ages_by_name.items())
    def find_name(age):
      return names_by_age[age]

donc vous pourriez faire:

find_teen_by_age = create_name_finder({'george':16,'amber':19})
...
find_teen_by_age(search_age)

notez que j'ai renommé list en ages_by_name car le premier est un type prédéfini.

0
répondu eold 2014-10-17 17:53:25
dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
key = [filter( lambda x: dictionary[x] == k  , dictionary ),[None]][0] 
# key = None from [None] which is a safeguard for not found.

pour l'utilisation de plusieurs occurrences:

keys = [filter( lambda x: dictionary[x] == k  , dictionary )]
0
répondu Cesar 2018-04-20 13:31:21