Quería probar si existe una clave en un diccionario antes de actualizar el valor de la clave. Escribí el siguiente código:
if 'key1' in dict.keys():
print "blah"
else:
print "boo"
Creo que esta no es la mejor manera de lograr esta tarea. ¿Hay una mejor manera de probar una clave en el diccionario?
python
dictionary
Mohan Gulati
fuente
fuente
dict.keys()
crean una lista de claves, de acuerdo con la documentación docs.python.org/2/library/stdtypes.html#dict.keys, pero me sorprendería si este patrón no estuviera optimizado para, en una implementación seria, traducir aif 'key1' in dict:
.x in dict.keys()
para comprobar si hay llaves. Y eso sucedió porque la forma habitual para iterar sobre las claves de Java estáfor (Type k : dict.keySet())
, este hábito causandofor k in dict.keys()
a se siente más natural quefor k in dict
(¿qué debería estar bien en términos de rendimiento?), pero luego comprobar las teclasif k in dict.keys()
también se vuelve , lo cual es un problema ...if k in dict_:
prueba la presencia de k en las CLAVES de dict_, por lo que aún no es necesariodict_.keys()
. (Esto me ha mordido, ya que me dice que está probando un valor en dict. Pero no lo es.)Respuestas:
in
es la forma prevista para probar la existencia de una clave en adict
.Si desea un valor predeterminado, siempre puede usar
dict.get()
:y si siempre quisiste asegurar un valor predeterminado para cualquier clave que puedas usar
dict.setdefault()
repetidamente odefaultdict
desde elcollections
módulo, así:pero en general, la
in
palabra clave es la mejor manera de hacerlo.fuente
get
si voy a sacar el elemento del diccionario de todos modos. No tiene sentido usarin
y sacar el elemento del diccionario.in
es la mejor manera de hacerlo.0
por ejemplo. Aprendí esto de la manera difícil: /No tienes que llamar a las teclas:
Eso será mucho más rápido ya que utiliza el hashing del diccionario en lugar de hacer una búsqueda lineal, lo que haría las teclas de llamada.
fuente
if key in d1
tomó0.17265701293945312
segundos. Llamadasif key in d1.keys()
tomadas0.23871088027954102
: esta es la definición clásica de una microoptimización. Ahorrar0.07884883880615234
segundos no es un aumento de rendimiento.keys()
le brinda un beneficio computacional de .01 segundo Para ~ 500,000 llaves, no llamarkeys()
le brinda .1 segundo beneficio. Para ~ 5,000,000 llaves, no llamarkeys()
es .4 segundos más rápido, pero para 50,000,000 llaves ¡ LLAMARkeys()
ES 3 SEGUNDOS MÁS RÁPIDO!Puede probar la presencia de una clave en un diccionario, utilizando la palabra clave in :
Un uso común para verificar la existencia de una clave en un diccionario antes de mutarlo es inicializar el valor por defecto (por ejemplo, si sus valores son listas, por ejemplo, y desea asegurarse de que haya una lista vacía a la que pueda agregar al insertar el primer valor para una clave). En casos como esos, puede encontrar el
collections.defaultdict()
tipo de interés.En el código anterior, también puede encontrar algunos usos de
has_key()
, un método obsoleto para verificar la existencia de claves en los diccionarios (solo usekey_name in dict_name
, en su lugar).fuente
key in dict.keys()
. Intente eliminar todo el código excepto este control y vea cuál es su resultado.Puedes acortar esto:
Sin embargo, esto es, en el mejor de los casos, una mejora cosmética. ¿Por qué crees que esta no es la mejor manera?
fuente
Para obtener información adicional sobre la ejecución rápida de los métodos propuestos de la respuesta aceptada (bucles de 10 m):
'key' in mydict
tiempo transcurrido 1.07 segundosmydict.get('key')
tiempo transcurrido 1.84 segundosmydefaultdict['key']
tiempo transcurrido 1.07 segundosPor lo tanto, el uso
in
odefaultdict
se recomiendan contraget
.fuente
get
1.84s es <1.07 * 2 ;-PRecomendaría usar el
setdefault
método en su lugar. Parece que hará todo lo que quieras.fuente
setdefault
tiene que ver con la pregunta del OP?El diccionario en python tiene un método get ('clave', predeterminado). Por lo tanto, puede establecer un valor predeterminado en caso de que no haya una clave.
fuente
¿Qué pasa con el uso de EAFP (más fácil pedir perdón que permiso):
Ver otras publicaciones SO:
Usar try vs if en python o
Comprobando la existencia de miembros en Python
fuente
Usando operador ternario:
fuente
Las formas en que puede obtener los resultados son:
Lo que es mejor depende de 3 cosas:
Lee mas: http://paltman.com/try-except-performance-in-python-a-simple-test/
Uso de try / block en lugar de 'in' o 'if':
fuente
2to3
, y vi que la sintaxis sin prueba siempre es más rápida que con la sintaxis con prueba, incluso en el caso de que la clave esté en el dict.Solo Python 2: (y Python 2.7
in
ya es compatible )puedes usar el método has_key ():
fuente
.has_key()
ha sido desaprobado ; debe usarin
como se muestra en otras respuestas.Solo un FYI que agrega a Chris. B (mejor respuesta):
También funciona; la razón es que la llamada
int()
devuelve,0
que es lo quedefaultdict
hace detrás de escena (cuando se construye un diccionario), de ahí el nombre "Función de fábrica" en la documentación.fuente
defaultdict(lambda: 0)
lugar de hacerlodefaultdict(int)
porque creo que está más claro lo que está sucediendo; el lector no necesita saber lo que obtienes0
si llamasint()
sin argumentos. YMMV.Para tener la idea de cómo hacerlo, primero inspeccionamos qué métodos podemos llamar en el diccionario. Aquí están los métodos:
El método brutal para verificar si la clave ya existe puede ser el
get()
método:Los otros dos métodos y sonidos interesantes parecen demasiado trabajo. Así que examinemos si es el método correcto para nosotros. Tenemos nuestro dict :
items()
keys()
get()
d
La impresión muestra que la clave que no tenemos regresará
None
:Nosotros
podemosusar eso para obtener la información si la clave está presente o no. Pero considere esto si creamos un dict con un solokey:None
:Liderar ese
get()
método no es confiable en caso de que algunos valores lo seanNone
. Esta historia debería tener un final más feliz. Si usamos elin
comparador:Obtenemos los resultados correctos. Podemos examinar el código de bytes de Python:
Esto muestra que el
in
operador de comparación no solo es más confiable sino incluso más rápido queget()
.fuente
.get()
puede tener un segundo argumento para eldefault
valor, que podría usarse para manejar el problema dondekey:None
. ejemplo:d.get("key", False)
.get()
Es la forma más rápida. Otra opción es asignar en untry
/except
bloqueEl diccionario de Python tiene el método llamado
__contains__
. Este método devolverá True si el diccionario tiene la clave; de lo contrario, devuelve False.fuente
__contains__
directamente. La forma correcta de hacerlo es utilizar elin
operador, que es elcontainment check
que invoca la__contains__
función.foo = x['foo'] if x.__contains__('foo') else 'bar'
. ¿Alguna idea de cómo podría usar elin
operador como parte de esta expresión?foo = x['foo'] if 'foo' in x else 'bar'
Compartir una forma más de verificar si existe una clave utilizando operadores booleanos.
Esto vuelve
Explicación
En primer lugar usted debe saber que en Python,
0
,None
, o los objetos con longitud cero a evaluarFalse
. Todo lo demás se evalúa aTrue
. Las operaciones booleanas se evalúan de izquierda a derecha y devuelven el operando no verdadero o falso.Veamos un ejemplo:
Como se
'Some string'
evalúa comoTrue
, el resto delor
no se evalúa y no se genera división por error cero.Pero si cambiamos el orden
1/0
se evalúa primero y se genera una excepción:Podemos usar esto para el patrón para verificar si existe una clave.
hace lo mismo que
Esto ya devuelve el resultado correcto si la clave existe, pero queremos que imprima 'boo' cuando no existe. Entonces, tomamos el resultado y
or
con'boo'
fuente
Puede usar el
for
bucle para iterar sobre el diccionario y obtener el nombre de la clave que desea encontrar en el diccionario, luego verifique si existe o no con laif
condición:fuente
it is exist
ynot exist