Obtenir la clé par valeur dans le dictionnaire

632

J'ai créé une fonction qui recherchera les âges dans un Dictionaryet affichera 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 pas comment montrer le nom de la personne. De plus, je reçois un en KeyErrorraison de la ligne 5. Je sais que ce n'est pas correct, mais je ne peux pas comprendre comment le faire rechercher en arrière.

user998316
la source
Trouveriez-vous un mot basé sur sa définition dans un dictionnaire? NAN.
Jossie Calderon

Réponses:

563

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

dictionary = {'george': 16, 'amber': 19}
search_age = input("Provide age")
for name, age in dictionary.items():  # for name, age in dictionary.iteritems():  (for Python 2.x)
    if age == search_age:
        print(name)
Cat Plus Plus
la source
137
Au Python 3.x list.items()lieu de list.iteritems()devrait être utilisé
Yuriy Petrovskiy
63
Je ne suis pas d'accord ... la réponse d'agf ci-dessous est plus constructive. Un cas d'utilisation parfaitement raisonnable n'est pas «involontaire» (la compréhension de la liste convient de toute façon à un tel cas d'utilisation). Un dictpeut être pour plusieurs choses à des moments différents; les clés et les valeurs ont un sens clair, bien sûr, mais "des dictarticles avec une valeur donnée" est une demande parfaitement raisonnable. La recommandation d'utiliser une liste de paires écarterait le contexte selon lequel un élément est une « définition » de l'autre, par exemple dans les listes de paramètres ...
Louis Maddox
1
Je ne suis pas d'accord avec cette réponse. Le fait qu'il s'agisse d'une possibilité, comme l'a montré la réponse de Stênio Elson, n'implique pas qu'elle n'était pas destinée à être utilisée en tant que telle. Pas du tout utile.
Tropicalrambler
Souhaitez-vous trouver un mot dans un dictionnaire basé sur sa définition? NAN. @Tropicalrambler
Jossie Calderon
Bien que vous ayez un point de vue qu'une utilisation standard pour un dictionnaire de mots est de rechercher la définition du mot avec mot = clé et définition = valeur, les langages de programmation d'aujourd'hui vous permettent de rechercher par valeur si nécessaire. Si vous travaillez avec un objet paire clé: valeur (appelez-le dictionnaire, tuple, quel que soit le nom pour la langue). En python, c'est un fait que vous pouvez toujours indexer les valeurs de la structure pour trouver les clés correspondantes.
Tropicalrambler
599
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

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()en Python 3: Comment puis-je obtenir la liste des valeurs de dict?

Stênio Elson
la source
23
Ça a l'air super mais ça marche toujours? Je veux dire, les fonctions list.keys()et list.values()génèrent-elles des éléments dans le même ordre?
iskorum
17
Oui, ils sont garantis pour être cohérents. De plus, l'ordre est garanti de ne pas changer d'itérations tant que le dictionnaire n'est pas modifié.
Veedrac
9
Cela semble être une bonne solution mais l'index n'a donné qu'une seule valeur à droite, donc si vous avez plusieurs valeurs égales, alors il devrait retourner plusieurs clés à droite?
James Sapam
12
@ArtOfWarfare docs.python.org/3/library/stdtypes.html#dict-views , "Si les vues des clés, des valeurs et des éléments sont itérées sans modification intermédiaire du dictionnaire, l'ordre des éléments correspondra directement."
Veedrac
5
@sinekonata: Il effectue toujours une boucle coûteuse sous le capot; la boucle est juste cachée à l'intérieur de la indexméthode.
user2357112 prend en charge Monica
252

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

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

Vous pouvez décompresser le tuple en deux variables distinctes dans la forboucle, puis faire correspondre l'âge.

Vous devriez également envisager d'inverser le dictionnaire si vous cherchez généralement par âge, et que deux personnes n'ont pas le même âge:

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

de sorte que vous pouvez rechercher le nom d'un âge en faisant simplement

mydict[search_age]

Je l'ai appelé mydictau lieu de listparce que listc'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 toutes les personnes ayant un âge donné sur une seule ligne:

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

ou s'il n'y a qu'une seule personne à chaque âge:

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

qui vous donnera juste Nones'il n'y a personne avec cet âge.

Enfin, si le dictest long et que vous êtes sur Python 2, vous devriez envisager d'utiliser .iteritems()plutôt .items()que Cat Plus Plus dans sa réponse, car il n'a pas besoin de faire une copie de la liste.

agf
la source
9
C'est exact, mais si vous allez faire une recherche linéaire, vous pourriez aussi bien remplacer le dictpar une liste de paires.
Fred Foo
9
À moins que votre action habituelle ne recherche les âges par leur nom, auquel cas a un dictsens.
agf
2
Il semble particulier de supposer qu'il n'y a qu'une seule personne à chaque âge, alors que d'un autre côté, il est tout à fait logique que chaque personne ait un seul âge.
Dannid
@Dannid Oui, mais le problème peut être facilement généralisé. Par exemple, vous pouvez avoir une table de recherche avec des clés uniques et leurs valeurs uniques correspondantes. Vous pouvez ensuite rechercher les choses symétriquement value --> keyoukey --> value
pfabri
68

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

Voici quelques tests que j'ai exécutés (sur un MacBook Pro 2012)

>>> 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()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

Cela montre donc que pour un petit dict, la méthode 1 est la plus rapide. Cela est probablement dû au fait qu'elle renvoie la première correspondance, par opposition à toutes les correspondances comme la méthode 2 (voir la 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 assez différents (exécutés cette fois 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 que la taille de votre dict affectera la méthode que vous choisissez.

Remarques: La méthode 2 renvoie 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 envisagé l'utilisation de la mémoire. Je ne sais pas si la méthode 3 crée 2 listes supplémentaires (clés () et valeurs ()) et les stocke en mémoire.

Patrick
la source
6
Juste une mise à jour: il semble que dict.values ​​() et dict.keys () retournent tous deux des listes qui référencent les objets du dict d'origine, donc la méthode 3 est aussi celle qui utilise le moins de mémoire (elle ne crée que deux objets de liste mince qui enveloppent le contenu des dits, tandis que les autres créent des éléments d'itérateur
Patrick
Je voulais juste le comparer moi-même, faire défiler vers le bas, bam là vous l'avez. Merci! Techniquement, comme vous l'avez déjà souligné, la méthode 2 ne fait pas exactement la même chose que 1 et 3 car elle renvoie toutes les correspondances. serait bien de voir les résultats pour par exemple return next ([..]).
BluBb_mADe
Une autre note importante à faire est la version Python. Je sais que certaines versions ont des implémentations de méthodes plus efficaces que d'autres.
ArtOfWarfare
@Patrick: toutes les méthodes utilisent des références directes aux valeurs et aux clés, il n'y a aucun avantage de mémoire pour aucune. Sauf en Python 3 .keys()et` .values()retourne les vues de dictionnaire, qui sont légères.
Martijn Pieters
53

version à une ligne: (i est un ancien dictionnaire, p est un dictionnaire inversé)

explication: i.keys()et i.values()renvoie respectivement deux listes avec les clés et les valeurs du dictionnaire. La fonction zip a la capacité de lier des listes pour produire un dictionnaire.

p = dict(zip(i.values(),i.keys()))

Avertissement: cela ne fonctionnera que si les valeurs sont hachables et uniques.

chatte
la source
Oui, cela fonctionnera: stackoverflow.com/questions/835092/…
The Unfun Cat
17
... et lorsqu'il n'y a pas de valeurs en double.
ely
3
Beau. Par rapport au commentaire ci-dessus, bien sûr, cela ne fonctionne que lorsqu'il n'y a pas de valeurs en double, mais ensuite, la question qui a démarré ce fil suppose que nous avons une fonction un à un, donc étant donné cette hypothèse, c'est la plus élégante réponse de loin.
John Strong
1
développer les valeurs hachables: si vos valeurs sont des listes / ensembles, convertissez-les en tuple pour que cela fonctionne (elles doivent toujours être uniques).
muon
28
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}
Jelen
la source
5
Et s'il y a une autre clé qui a la même valeur que a? Peut être de manière pythonique. Mais ce n'est pas une bonne idée.
7H3 IN5ID3R
bon point, j'ai ajouté une solution qui fonctionne avec des valeurs non uniques
Jelen
26
key = next((k for k in my_dict if my_dict[k] == val), None)
faham
la source
Puis-je également avoir un «autre» dans cette même ligne? Pour le cas où ma valeur n'est pas dans les valeurs dict
Srishti Gupta
lKey = [k for k, v in lDictionary.iteritems() if v == lValue][0] or 'else-key'
faham
14

Essayez ce one-liner pour inverser un dictionnaire:

reversed_dictionary = dict(map(reversed, dictionary.items()))
johnaphun
la source
1
Cela a très bien fonctionné pour mon programme de cryptage et de décryptage, merci!
Christian R
Source
pfabri
@pfabri ???????
johnaphun
14

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 des clés et les valeurs des clés, comme on le voit 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 la même que cette autre réponse .

Rafael Valero
la source
Excellent!! Pour Python3, ce serait items () au lieu d' iteritems () .
kkgarg Il y a
12

Si vous souhaitez rechercher la clé par la valeur, vous pouvez utiliser une compréhension de dictionnaire pour créer un dictionnaire de recherche, puis l'utiliser pour rechercher la clé à partir de la valeur.

lookup = {value: key for key, value in self.data}
lookup[value]
Safia Abdalla
la source
11

Vous pouvez obtenir la clé à l'aide dict.keys(), dict.values()et les list.index()méthodes, voir des 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)]
Andriy Ivaneyko
la source
2
vous n'utilisez pas de search_agevar définie sur la ligne suivante ... Peut-être que vous devriez remplacer valuepar search_age?
Andersson
2
J'obtiens cette erreur: l'objet 'dict_values' n'a pas d'attribut 'index'
Blue_Elephant
@Blue_Elephant pourriez-vous s'il vous plaît fournir un extrait de code que vous avez une erreur et une version python (également une impression de type(dict_values)serait utile)?
Andriy Ivaneyko
9

Voici mon point de vue sur ce problème. :) Je viens de commencer à apprendre Python, donc j'appelle cela:

"La solution compréhensible pour les débutants".

#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!
Deithrian
la source
9
get_key = lambda v, d: next(k for k in d if d[k] is v)
Brett
la source
Nice one-liner. Cependant, isdevrait être utilisé que pour les tests de l' égalité des singletons ( None, True, Falseetc.). Le fait que CPython réutilise les littéraux de chaîne (et a = 'foobar'; a is 'foobar'est donc True) est un détail d'implémentation et ne doit pas être invoqué.
piit79
1
Et un autre commentaire: get_keylancera StopIterationsi la valeur n'existe pas dans le dictionnaire - il serait préférable d'utiliser next(..., None)ce qui retournerait Nonesi la valeur n'était pas trouvée.
piit79
Une légère modification fonctionnera si le dictionnaire ne contient pas d'éléments simples mais définit:get_first_key = lambda v, d: next((k for k in d if (v in d[k] is not None)), None)
supernova
7

Pensez à utiliser des pandas. Comme indiqué dans "Python for Data Analysis" de William McKinney

Une autre façon de penser une série est une dictée ordonnée de longueur fixe, car il s'agit d'un mappage de valeurs d'index à des valeurs de données. Il peut être utilisé 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, procédez comme suit:

lookup_list[lookup_list.values == 19]

Ce qui donne:

Out[1]: 
amber    19
dtype: int64

Si vous devez faire autre chose avec la sortie, la transformation de la réponse en liste peut être utile:

answer = lookup_list[lookup_list.values == 19].index
answer = pd.Index.tolist(answer)
Axel
la source
Il est le créateur des pandas. Il est plus connu sous le nom de Wes.
Axel
6

Ici, Recover_key prend le dictionnaire et la valeur à trouver dans le dictionnaire. Nous faisons ensuite une boucle sur les clés dans le dictionnaire et faisons une comparaison avec celle de la valeur et retournons cette clé particulière.

def recover_key(dicty,value):
    for a_key in dicty.keys():
        if (dicty[a_key] == value):
            return a_key
shishir
la source
5

nous pouvons obtenir le Keyde dict:

def getKey(dct,value):
     return [key for key in dct if (dct[key] == value)]
Sakhri Houssem
la source
4
for name in mydict:
    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
patrick
la source
1
L'utilisation d'une boucle for et d'un ajout est beaucoup plus lente qu'une compréhension de liste et elle est également plus longue.
alexpinho98
3

on y répond, mais cela pourrait être fait avec une utilisation sophistiquée de «carte / réduire», 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()))
formiaczek
la source
3

Cat Plus Plus a mentionné que ce n'est pas la façon dont 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 un mappage de K (l'ensemble de clés) à V (les valeurs) - mais pas l'inverse. Si vous déréférencer un dict, vous vous attendez à obtenir exactement une valeur retournée. Mais, il est parfaitement légal que différentes clés soient mappées sur la même valeur, par exemple:

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

Lorsque vous recherchez une clé par sa valeur correspondante, vous inversez essentiellement le dictionnaire. Mais une cartographie n'est pas forcément inversible! Dans cet exemple, demander la clé correspondant à v1 pourrait donner k1 ou k3. Devriez-vous retourner les deux? 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'une telle opération.

Dan Ahlquist
la source
3

voici mon point de vue là-dessus. C'est bon pour afficher plusieurs résultats au cas où vous en auriez besoin. J'ai donc ajouté la liste également

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

user3649211
la source
3
d= {'george':16,'amber':19}

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

La sortie est la suivante:

-> prints george
Jeroen
la source
[k pour k, v dans d.items () si v == 16]
auro
3

Il n'y a pas de moyen facile de trouver une clé dans une liste en «recherchant» la valeur. Cependant, si vous connaissez la valeur, en parcourant les clés, vous pouvez rechercher des valeurs dans le dictionnaire par l'élément. Si D [élément] où D est un objet dictionnaire, est égal à la clé que vous essayez de rechercher, 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)
Ethan
la source
3

Vous devez utiliser un dictionnaire et inverser ce dictionnaire. Cela signifie que vous avez besoin d'une autre structure de données. Si vous êtes en python 3, utilisez le enummodule mais si vous utilisez python 2.7, utilisezenum34 qui est de retour porté 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 
hamidfzm
la source
2
def get_Value(dic,value):
    for name in dic:
        if dic[name] == value:
            del dic[name]
            return name
Raj Damani
la source
1
pourquoi retirer la clé du dictionnaire? cela ne répond pas à la question
Jean-François Fabre
2

Juste ma réponse dans lambdaet filter.

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age  , dictionary )
Bishwas Mishra
la source
1

déjà répondu, mais comme plusieurs personnes ont mentionné l'inversion du dictionnaire, voici comment vous le faites en une seule ligne (en supposant un mappage 1: 1) et quelques données de perf différentes:

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 que ce n'est pas 1: 1, vous pouvez toujours créer un mappage inverse raisonnable avec quelques lignes:

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

à quel point est-ce lent: plus lent qu'une simple recherche, mais pas aussi lent que vous le pensez - sur un dictionnaire 100000 entrées «droit», une recherche «rapide» (c'est-à-dire la recherche d'une valeur qui devrait être au début des touches) était environ 10 fois plus rapide que l'inversion de l'ensemble du dictionnaire, et une recherche «lente» (vers la fin) environ 4 à 5 fois plus rapide. Donc, après une dizaine de recherches au maximum, il est amorti.

la deuxième version (avec listes par article) prend environ 2,5 fois plus 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

A également eu des résultats intéressants avec ifilter. Théoriquement, ifilter devrait être plus rapide, en ce sens que nous pouvons utiliser itervalues ​​() et ne pas avoir à créer / parcourir la liste de valeurs entière. En pratique, les résultats étaient ... bizarres ...

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

Ainsi, pour les petits décalages, il était considérablement 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 vers la fin de la liste, il a été considérablement plus lent (15,1 ms contre les mêmes 1,48 ms). Les petites économies au bas de gamme ne valent pas le coût au haut de gamme, à mon humble avis.

Corley Brigman
la source
Je veux tellement que cela (reverseict = defaultdict (list) reverseict [value] .append (key) for key, value in largedict.iteritems ()]) fonctionne, mais en utilisant Python 2.7.3, j'obtiens une erreur de syntaxe sur le mot 'for'
slashdottir
c'est bien ce que vous avez tapé? vous en manquez un [, si c'est le cas. sinon, assurez-vous qu'il est sur deux lignes, ou mettez un ;entre eux sinon.
Corley Brigman
1

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
Denis Kutlubaev
la source
1

Voici une solution qui fonctionne à la fois en Python 2 et 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 d'assistance qui mettra en cache ce dictionnaire inversé comme suit:

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

ou encore plus généralement une usine qui créerait une méthode de recherche de nom 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]

vous pourrez donc faire:

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

Notez que j'ai changé listde nom ages_by_namecar le premier est un type prédéfini.

eold
la source
1

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 faux qu'il semble qu'ils imprimeraient une époque, mais cela 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

la source
1
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 plusieurs occurrences, utilisez:

keys = [filter( lambda x: dictionary[x] == k  , dictionary )]
César
la source
*** NameError: global name 'dictionary' is not defined
Bishwas Mishra
filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age , dictionary )
Bishwas Mishra