Existe-t-il un moyen simple de trouver une clé en connaissant la valeur dans un dictionnaire?
Tout ce que je peux penser, c'est ceci:
key = [key for key, value in dict_obj.items() if value == 'value'][0]
python
dictionary
RadiantHex
la source
la source
iteritems
comme pour moi cela fait une différence 40x plus rapide ... en utilisant la méthode () .nextreverse_dictionary = {v:k for k,v in dictionary.items()}
Réponses:
Il n'y en a pas. N'oubliez pas que la valeur peut être trouvée sur n'importe quel nombre de clés, y compris 0 ou plus de 1.
la source
</sigh>
Votre compréhension de liste passe par tous les éléments du dict pour trouver toutes les correspondances, puis renvoie simplement la première clé. Cette expression de générateur n'itérera que dans la mesure nécessaire pour renvoyer la première valeur:
où
dd
est le dict. Sera déclenchéStopIteration
si aucune correspondance n'est trouvée, vous voudrez peut-être l'attraper et renvoyer une exception plus appropriée commeValueError
ouKeyError
.la source
keys = { key for key,value in dd.items() if value=='value' }
pour obtenir l'ensemble de toutes les clés si plusieurs correspondances.Il y a des cas où un dictionnaire est un: un mappage
Par exemple,
Votre approche est correcte si vous ne faites qu'une seule recherche. Cependant, si vous devez faire plus d'une recherche, il sera plus efficace de créer un dictionnaire inverse
S'il existe une possibilité de plusieurs clés avec la même valeur, vous devrez spécifier le comportement souhaité dans ce cas.
Si votre Python est 2.6 ou plus ancien, vous pouvez utiliser
la source
ivd=dict([(v,k) for (k,v) in d.items()])
invd = { v:k for k,v in d.items() }
Cette version est 26% plus courte que la vôtre mais fonctionne de manière identique, même pour les valeurs redondantes / ambiguës (renvoie la première correspondance, comme la vôtre). Cependant, il est probablement deux fois plus lent que le vôtre, car il crée deux fois une liste à partir du dict.
Ou si vous préférez la brièveté à la lisibilité, vous pouvez enregistrer un caractère supplémentaire avec
Et si vous préférez l'efficacité, l' approche de @ PaulMcGuire est meilleure. S'il y a beaucoup de clés qui partagent la même valeur, il est plus efficace de ne pas instancier cette liste de clés avec une compréhension de liste et d'utiliser à la place un générateur:
la source
dict.keys()
et ildict.values()
est garanti de correspondre tant que ledict
n'est pas muté entre les appels.Comme cela est toujours très pertinent, le premier succès de Google et je passe juste un peu de temps à le comprendre, je posterai ma solution (travaillant en Python 3):
Cela vous donnera la première valeur qui correspond.
la source
Peut-être qu'une classe semblable à un dictionnaire comme
DoubleDict
ci-dessous est ce que vous voulez? Vous pouvez utiliser l'une des métaclasses fournies en conjonction avecDoubleDict
ou éviter d'utiliser une métaclasse du tout.la source
Non, vous ne pouvez pas le faire efficacement sans chercher dans toutes les clés et vérifier toutes leurs valeurs. Vous aurez donc besoin de
O(n)
temps pour le faire. Si vous avez besoin de faire beaucoup de telles recherches, vous devrez le faire efficacement en construisant un dictionnaire inversé (peut être fait également dansO(n)
) et en effectuant une recherche à l'intérieur de ce dictionnaire inversé (chaque recherche prendra en moyenneO(1)
).Voici un exemple de la façon de construire un dictionnaire inversé (qui pourra faire un à plusieurs mappages) à partir d'un dictionnaire normal:
Par exemple si votre
tu
h_reversed
serasla source
À ma connaissance, il n'y en a pas, une façon de le faire est de créer un dict pour la recherche normale par clé et un autre dict pour la recherche inversée par valeur.
Il y a un exemple d'une telle implémentation ici:
http://code.activestate.com/recipes/415903-two-dict-classes-which-can-lookup-keys-by-value-an/
Cela signifie que la recherche des clés pour une valeur peut entraîner plusieurs résultats qui peuvent être renvoyés sous forme de liste simple.
la source
Je sais que cela peut être considéré comme un `` gaspillage '', mais dans ce scénario, je stocke souvent la clé en tant que colonne supplémentaire dans l'enregistrement de valeur:
c'est un compromis et se sent mal, mais c'est simple et fonctionne et dépend bien sûr du fait que les valeurs sont des tuples plutôt que de simples valeurs.
la source
Faire un dictionnaire inversé
Si vous avez beaucoup de recherches inversées à faire
la source
Grâce aux valeurs dans le dictionnaire peuvent être des objets de toute sorte, elles ne peuvent pas être hachées ou indexées d'une autre manière. Donc, trouver la clé par la valeur n'est pas naturel pour ce type de collection. Toute requête comme celle-ci ne peut être exécutée qu'en temps O (n). Donc, si c'est une tâche fréquente, vous devriez jeter un œil pour une indexation de clé comme Jon sujjested ou peut-être même un index spatial (DB ou http://pypi.python.org/pypi/Rtree/ ).
la source
J'utilise des dictionnaires comme une sorte de "base de données", je dois donc trouver une clé que je peux réutiliser. Dans mon cas, si la valeur d'une clé est
None
, alors je peux la prendre et la réutiliser sans avoir à "allouer" un autre identifiant. Je pensais juste que je le partagerais.J'aime celui-ci parce que je n'ai pas à essayer de détecter des erreurs telles que
StopIteration
ouIndexError
. Si une clé est disponible, ellefree_id
en contiendra une. S'il n'y en a pas, ce sera simplement le casNone
. Probablement pas pythonique, mais je ne voulais vraiment pas utiliser untry
ici ...la source