J'ai créé une fonction qui recherchera les âges dans un Dictionary
et 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 KeyError
raison 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.
python
dictionary
user998316
la source
la source
Réponses:
Il n'y en a pas.
dict
n'est pas destiné à être utilisé de cette façon.la source
Python 3.x
list.items()
lieu delist.iteritems()
devrait être utilisédict
peut être pour plusieurs choses à des moments différents; les clés et les valeurs ont un sens clair, bien sûr, mais "desdict
articles 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 ...Ou en Python 3.x:
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?la source
list.keys()
etlist.values()
génèrent-elles des éléments dans le même ordre?index
méthode.Si vous voulez à la fois le nom et l'âge, vous devez utiliser
.items()
ce qui vous donne des(key, value)
tuples clés :Vous pouvez décompresser le tuple en deux variables distinctes dans la
for
boucle, 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:
de sorte que vous pouvez rechercher le nom d'un âge en faisant simplement
Je l'ai appelé
mydict
au lieu delist
parce quelist
c'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:
ou s'il n'y a qu'une seule personne à chaque âge:
qui vous donnera juste
None
s'il n'y a personne avec cet âge.Enfin, si le
dict
est 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.la source
dict
par une liste de paires.dict
sens.value --> key
oukey --> value
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)
Résultats de
profile.run()
chaque méthode 100000 fois:Méthode 1:
Méthode 2:
Méthode 3:
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:
Méthode 2:
Méthode 3:
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.
la source
.keys()
et`.values()
retourne les vues de dictionnaire, qui sont légères.version à une ligne: (i est un ancien dictionnaire, p est un dictionnaire inversé)
explication:
i.keys()
eti.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.Avertissement: cela ne fonctionnera que si les valeurs sont hachables et uniques.
la source
ou mieux
la source
la source
lKey = [k for k, v in lDictionary.iteritems() if v == lValue][0] or 'else-key'
Essayez ce one-liner pour inverser un dictionnaire:
la source
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 .
ou
qui est essentiellement la même que cette autre réponse .
la source
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.
la source
Vous pouvez obtenir la clé à l'aide
dict.keys()
,dict.values()
et leslist.index()
méthodes, voir des exemples de code ci - dessous:la source
search_age
var définie sur la ligne suivante ... Peut-être que vous devriez remplacervalue
parsearch_age
?type(dict_values)
serait utile)?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".
.
.
la source
la source
is
devrait être utilisé que pour les tests de l' égalité des singletons (None
,True
,False
etc.). Le fait que CPython réutilise les littéraux de chaîne (eta = 'foobar'; a is 'foobar'
est doncTrue
) est un détail d'implémentation et ne doit pas être invoqué.get_key
lanceraStopIteration
si la valeur n'existe pas dans le dictionnaire - il serait préférable d'utilisernext(..., None)
ce qui retourneraitNone
si la valeur n'était pas trouvée.get_first_key = lambda v, d: next((k for k in d if (v in d[k] is not None)), None)
Pensez à utiliser des pandas. Comme indiqué dans "Python for Data Analysis" de William McKinney
Pour interroger votre série, procédez comme suit:
Ce qui donne:
Si vous devez faire autre chose avec la sortie, la transformation de la réponse en liste peut être utile:
la source
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.
la source
nous pouvons obtenir le
Key
dedict
:la source
la source
on y répond, mais cela pourrait être fait avec une utilisation sophistiquée de «carte / réduire», par exemple:
la source
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:
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.
la source
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
Et c'est tout...
la source
La sortie est la suivante:
la source
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.
la source
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
enum
module mais si vous utilisez python 2.7, utilisezenum34
qui est de retour porté pour python 2.Exemple:
la source
la source
Juste ma réponse dans
lambda
etfilter
.la source
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:
2.7+:
si vous pensez que ce n'est pas 1: 1, vous pouvez toujours créer un mappage inverse raisonnable avec quelques lignes:
à 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.
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 ...
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.
la source
[
, si c'est le cas. sinon, assurez-vous qu'il est sur deux lignes, ou mettez un;
entre eux sinon.Parfois, int () peut être nécessaire:
la source
Voici une solution qui fonctionne à la fois en Python 2 et Python 3:
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: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
vous pourrez donc faire:
Notez que j'ai changé
list
de nomages_by_name
car le premier est un type prédéfini.la source
Voici comment vous accédez au dictionnaire pour faire ce que vous voulez:
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:
Mieux encore:
la source
Pour plusieurs occurrences, utilisez:
la source
*** NameError: global name 'dictionary' is not defined
filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age , dictionary )