Comprobar si una clave dada ya existe en un diccionario


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?

Author: bluish, 2009-10-21

19 answers

in es la forma prevista para probar la existencia de una clave en un dict.

d = dict()

for i in xrange(100):
    key = i % 10
    if key in d:
        d[key] += 1
    else:
        d[key] = 1

Si desea un valor predeterminado, siempre puede usar dict.get():

d = dict()

for i in xrange(100):
    key = i % 10
    d[key] = d.get(key, 0) + 1

... y si desea garantizar siempre un valor predeterminado para cualquier clave, puede usar defaultdict desde el módulo collections, así:

from collections import defaultdict

d = defaultdict(lambda: 0)

for i in xrange(100):
    d[i % 10] += 1

... pero en general, la palabra clave in es la mejor manera de hacerlo.

 2346
Author: Chris B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-21 19:10:21

No tienes que llamar a las teclas:

if 'key1' in dict:
  print "blah"
else:
  print "boo"

Eso será mucho más rápido ya que usa el hash del diccionario en lugar de hacer una búsqueda lineal, lo que haría las teclas de llamada.

 1146
Author: Jason Baker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:53

Puede probar la presencia de una clave en un diccionario, usando la palabra clave in:

d = {'a': 1, 'b': 2}
'a' in d # <== evaluates to True
'c' in d # <== evaluates to False

Un uso común para verificar la existencia de una clave en un diccionario antes de mutarla es inicializar por defecto el valor (por ejemplo, si sus valores son listas, y desea asegurarse de que hay una lista vacía a la que puede agregar al insertar el primer valor para una clave). En casos como esos, puede encontrar la collections.defaultdict() escriba para ser de interés.

En mayores código, también puede encontrar algunos usos de has_key(), un método obsoleto para verificar la existencia de claves en diccionarios (solo use key_name in dict_name, en su lugar).

 233
Author: Michael Aaron Safyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-27 23:12:01

Puedes acortar esto:

if 'key1' in dict:
    ...

Sin embargo, esto es en el mejor de los casos una mejora cosmética. ¿Por qué crees que esta no es la mejor manera?

 76
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-21 19:06:40

Recomendaría usar el método setdefault en su lugar. Parece que hará todo lo que quieras.

>>> d = {'foo':'bar'}
>>> q = d.setdefault('foo','baz') #Do not override the existing key
>>> print q #The value takes what was originally in the dictionary
bar
>>> print d
{'foo': 'bar'}
>>> r = d.setdefault('baz',18) #baz was never in the dictionary
>>> print r #Now r has the value supplied above
18
>>> print d #The dictionary's been updated
{'foo': 'bar', 'baz': 18}
 41
Author: David Berger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-21 19:07:28

Para obtener información adicional sobre la velocidad de ejecución de los métodos propuestos de la respuesta aceptada (bucles de 10 m):

  • 'key' in mydict tiempo transcurrido 1.07 seg
  • mydict.get('key') tiempo transcurrido 1.84 seg
  • mydefaultdict['key'] tiempo transcurrido 1.07 seg

Por lo tanto, se recomienda usar in o defaultdict en contra de get.

 35
Author: Wtower,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-29 11:06:44

El diccionario en python tiene un método get('key', por defecto). Por lo tanto, puede establecer un valor predeterminado en caso de que no haya ninguna clave.

values = {...}
myValue = values.get('Key', None)
 24
Author: mafonya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-23 18:51:00

Qué hay de usar EAFP (más fácil pedir perdón que permiso):

try:
   blah = dict["mykey"]
   # key exists in dict
except KeyError:
   # key doesn't exist in dict

Ver otros mensajes SO:

Usando try vs if en python o

Comprobando la existencia de miembros en Python

 18
Author: HungryArthur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-10 19:22:43

Para comprobar puede utilizar has_key() método

if dict.has_key('key1'):
   print "it is there"

Si desea un valor, puede usar el método get()

a = dict.get('key1', expeced_type)

Si desea una tupla, lista o diccionario o cualquier cadena como valor predeterminado como valor devuelto, use get() método

a = dict.get('key1', {}).get('key2', [])
 16
Author: Debabrata,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-27 06:41:22

Usando el operador ternario:

message = "blah" if 'key1' in dict else "booh"
print(message)
 16
Author: Charitoo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-18 22:58:00

Solo un FYI añadiendo a Chris. B (mejor respuesta):

d = defaultdict(int)

También funciona; la razón es que llamar a int() devuelve 0 que es lo que defaultdict hace detrás de escena (al construir un diccionario), de ahí el nombre "Función de fábrica" en la documentación.

 13
Author: Mauricio Morales,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-19 18:12:35

Las formas en las que puedes obtener los resultados son:

Lo que es mejor depende de 3 cosas:

  1. El diccionario 'normalmente tiene la clave' o 'normalmente no tiene la clave'.
  2. ¿Tiene la intención de utilizar condiciones como si...else...elseif...¿else?
  3. ¿Qué tamaño tiene el diccionario?

Leer Más: http://paltman.com/try-except-performance-in-python-a-simple-test /

Uso de try / block en lugar de' in 'o'if':

try:
    my_dict_of_items[key_i_want_to_check]
except KeyError:
    # Do the operation you wanted to do for "key not present in dict".
else:
    # Do the operation you wanted to do with "key present in dict."
 12
Author: Bishwas Mishra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-21 07:05:44

Puedes usar el método has_key ():

if dict.has_key('xyz')==1:
    #update the value for the key
else:
    pass

O el método dict.get para establecer un valor predeterminado si no se encuentra:

mydict = {"a": 5}

print mydict["a"]            #prints 5
print mydict["b"]            #Throws KeyError: 'b'

print mydict.get("a", 0)     #prints 5
print mydict.get("b", 0)     #prints 0
 10
Author: wan kenobi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-07 22:03:25

print dict.get('key1', 'blah')

No imprime boo para los valores en el diccionario, pero logra el objetivo imprimiendo el valor de key1 para confirmar su existencia en su lugar.

 6
Author: gounc86,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-15 18:55:45

El diccionario Python tiene el método llamado __contains__. Este método devolverá True si el diccionario tiene la clave else devuelve False.

 >>> temp = {}

 >>> help(temp.__contains__)

Help on built-in function __contains__:

__contains__(key, /) method of builtins.dict instance
    True if D has a key k, else False.
 3
Author: Siva Gnanam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-26 11:02:49

Bueno.. Usted estará familiarizado con que buscar la existencia de un elemento en una lista o datos significa ir a través de todo (al menos para la lista desordenada, por ejemplo, dict.así que en lugar de usar Excepciones y Errores que surgen normalmente podemos evitar esa complejidad...

d={1:'a',2:'b'}
try:
    needed=d[3]
    print(needed)
except:
    print("Key doesnt exist")
 2
Author: Seenivasan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-09 11:55:00

La más fácil es si sabes qué clave (nombre clave) es buscar:

# suppose your dictionary is
my_dict = {'foo': 1, 'bar': 2}
# check if a key is there
if 'key' in my_dict.keys():   # it will evaluates to true if that key is present otherwise false.
    # do something

O también puede hacer simplemente como:

if 'key' in my_dict:   # it will evaluates to true if that key is present otherwise false.
    # do something
 0
Author: Tasneem Haider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-13 05:44:35

Utilizo el try/except; si se lanza una excepción, entonces la clave no está presente en el diccionario. ejemplo:

st = 'sdhfjaks'
d = {}
try:
    print d['st']
except Exception, e:
    print 'Key not in the dictionary'
 0
Author: Leonardo Maffei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-07 22:02:16

¿Por qué no usar el método has_key ()?

a = {}
a.has_key('b') => #False

a['b'] = 8
a.has_key('b') => #True
 -3
Author: wmorris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-09 18:36:06