¿Existe alguna forma sencilla de encontrar una clave conociendo el valor dentro de un diccionario?
Todo lo que puedo pensar es esto:
key = [key for key, value in dict_obj.items() if value == 'value'][0]
python
dictionary
RadiantHex
fuente
fuente
iteritems
como para mí esto hace una diferencia 40 veces más rápida ... usando el método () .nextreverse_dictionary = {v:k for k,v in dictionary.items()}
Respuestas:
No hay ninguno. No olvide que el valor se puede encontrar en cualquier número de claves, incluido 0 o más de 1.
fuente
</sigh>
La comprensión de su lista pasa por todos los elementos del dict encontrando todas las coincidencias, luego solo devuelve la primera clave. Esta expresión generadora solo iterará tanto como sea necesario para devolver el primer valor:
donde
dd
esta el dict. AumentaráStopIteration
si no se encuentra ninguna coincidencia, por lo que es posible que desee detectar eso y devolver una excepción más apropiada comoValueError
oKeyError
.fuente
keys = { key for key,value in dd.items() if value=='value' }
para obtener el conjunto de todas las claves si hay varias coincidencias.Hay casos en los que un diccionario es uno: un mapeo
P.ej,
Su enfoque está bien si solo está haciendo una única búsqueda. Sin embargo, si necesita hacer más de una búsqueda, será más eficiente crear un diccionario inverso.
Si existe la posibilidad de varias claves con el mismo valor, deberá especificar el comportamiento deseado en este caso.
Si su Python es 2.6 o anterior, puede usar
fuente
ivd=dict([(v,k) for (k,v) in d.items()])
invd = { v:k for k,v in d.items() }
Esta versión es un 26% más corta que la suya, pero funciona de manera idéntica, incluso para valores redundantes / ambiguos (devuelve la primera coincidencia, como la suya). Sin embargo, probablemente sea dos veces más lento que el suyo, porque crea una lista a partir del dict dos veces.
O si prefiere la brevedad a la legibilidad, puede guardar un carácter más con
Y si prefiere la eficiencia, el enfoque de @ PaulMcGuire es mejor. Si hay muchas claves que comparten el mismo valor, es más eficiente no crear una instancia de esa lista de claves con una lista de comprensión y, en su lugar, usar un generador:
fuente
dict.keys()
ydict.values()
se garantiza que se corresponderán siempre quedict
no se modifique entre llamadas.Dado que esto sigue siendo muy relevante, el primer éxito de Google y solo dedico un tiempo a resolver esto, publicaré mi solución (trabajando en Python 3):
Le dará el primer valor que coincida.
fuente
¿Quizás una clase similar a un diccionario como la que se
DoubleDict
muestra a continuación es lo que desea? Puede usar cualquiera de las metaclases proporcionadas junto conDoubleDict
o puede evitar usar cualquier metaclase en absoluto.fuente
No, no puede hacer esto de manera eficiente sin mirar todas las claves y verificar todos sus valores. Entonces necesitará
O(n)
tiempo para hacer esto. Si necesita hacer muchas de estas búsquedas, deberá hacerlo de manera eficiente construyendo un diccionario invertido (también se puede hacer enO(n)
) y luego haciendo una búsqueda dentro de este diccionario invertido (cada búsqueda tomará un promedioO(1)
).A continuación se muestra un ejemplo de cómo construir un diccionario inverso (que podrá hacer una asignación de uno a varios) a partir de un diccionario normal:
Por ejemplo, si tu
tu
h_reversed
seráfuente
No hay uno que yo sepa, sin embargo, una forma de hacerlo es crear un dictado para la búsqueda normal por clave y otro dictado para la búsqueda inversa por valor.
Hay un ejemplo de tal implementación aquí:
http://code.activestate.com/recipes/415903-two-dict-classes-which-can-lookup-keys-by-value-an/
Esto significa que buscar las claves para un valor podría dar como resultado múltiples resultados que se pueden devolver como una lista simple.
fuente
Sé que esto podría considerarse un 'desperdicio', pero en este escenario, a menudo guardo la clave como una columna adicional en el registro de valor:
es una compensación y se siente mal, pero es simple y funciona y, por supuesto, depende de que los valores sean tuplas en lugar de valores simples.
fuente
Hacer un diccionario inverso
Si tiene muchas búsquedas inversas que hacer
fuente
Los valores en el diccionario pueden ser objetos de cualquier tipo y no pueden ser indexados o indexados de otra manera. Por lo tanto, encontrar la clave por el valor no es natural para este tipo de colección. Cualquier consulta como esa se puede ejecutar solo en tiempo O (n). Entonces, si esta es una tarea frecuente, debe buscar alguna indexación de clave como Jon sujjested o tal vez incluso algún índice espacial (DB o http://pypi.python.org/pypi/Rtree/ ).
fuente
Estoy usando diccionarios como una especie de "base de datos", así que necesito encontrar una clave que pueda reutilizar. En mi caso, si el valor de una clave es
None
, entonces puedo tomarla y reutilizarla sin tener que "asignar" otra identificación. Solo pensé en compartirlo.Me gusta este porque no tengo que intentar detectar ningún error como
StopIteration
oIndexError
. Si hay una clave disponible,free_id
contendrá una. Si no lo hay, simplemente lo seráNone
. Probablemente no sea pitónico, pero realmente no quería usar untry
aquí ...fuente