Pregunta 'has_key ()' o 'in'?


Me pregunto qué es mejor hacer:

d = {'a': 1, 'b': 2}
'a' in d
True

o:

d = {'a': 1, 'b': 2}
d.has_key('a')
True

689
2017-08-24 16:30


origen


Respuestas:


in es definitivamente más pitónico.

De hecho has_key() fue eliminado en Python 3.x.


960
2017-08-24 16:33



in gana indiscutiblemente, no solo en elegancia (y no en desuso ;-) sino también en rendimiento, p. ej .:

$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'
10000000 loops, best of 3: 0.0983 usec per loop
$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'
1000000 loops, best of 3: 0.21 usec per loop

Si bien la siguiente observación no es siempre cierto, notará que generalmenteEn Python, la solución más rápida es más elegante y Pythonic. es por eso -mtimeit es TAN útil - no es sólo acerca de ahorrar cien nanosegundos aquí y allá! -)


221
2017-08-24 18:12



De acuerdo con Python documentos:

has_key() está en desuso en favor de    key in d.


69
2017-08-24 16:33



Utilizar dict.has_key() si (y solo si) su código debe ser ejecutable por versiones de Python anteriores a 2.3 (cuando key in dict Fue presentado).


34
2017-08-24 22:11



Hay un ejemplo donde in en realidad mata tu rendimiento.

Si utiliza in en un contenedor O (1) que solo implementa __getitem__ y has_key() pero no __contains__ convertirá una búsqueda O (1) en una búsqueda O (N) (como in vuelve a una búsqueda lineal a través de __getitem__)

La reparación es obviamente trivial:

def __contains__(self, x):
    return self.has_key(x)

19
2018-01-18 16:45



has_key es un método de diccionario, pero in funcionará en cualquier colección, e incluso cuando __contains__ Está perdido, in usará cualquier otro método para iterar la colección para descubrir.


12
2017-08-24 18:35



Python 2.x soporta has_key().

Soporte de Python 2.3+ y Python 3.x in.


10
2018-05-09 08:06



La solución para dict.has_key () está en desuso, use 'in' - editor de texto sublime 3

Aquí tomé un ejemplo de diccionario llamado 'edades' -

ages = {}

# Add a couple of names to the dictionary
ages['Sue'] = 23

ages['Peter'] = 19

ages['Andrew'] = 78

ages['Karren'] = 45

# use of 'in' in if condition instead of function_name.has_key(key-name).
if 'Sue' in ages:

    print "Sue is in the dictionary. She is", ages['Sue'], "years old"

else:

    print "Sue is not in the dictionary"

10
2018-02-23 10:29



Ampliando las pruebas de rendimiento de Alex Martelli con los comentarios de Adam Parkin ...

$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
Traceback (most recent call last):
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 301, in main
    x = t.timeit(number)
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 178, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
    d.has_key(12)
AttributeError: 'dict' object has no attribute 'has_key'

$ python2.7 -mtimeit -s'd=dict.fromkeys(range(  99))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0872 usec per loop

$ python2.7 -mtimeit -s'd=dict.fromkeys(range(1999))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0858 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(  99))' '12 in d'
10000000 loops, best of 3: 0.031 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d'
10000000 loops, best of 3: 0.033 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(  99))' '12 in d.keys()'
10000000 loops, best of 3: 0.115 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d.keys()'
10000000 loops, best of 3: 0.117 usec per loop

7
2017-12-30 05:16



Si su intención es usar un valor predeterminado en caso de que una clave no esté en el diccionario, entonces

my_dict.get('key') or default_value

es una forma de saltear el in comprobar. get devoluciones None si la clave no está en el diccionario La velocidad también es O (1) como con el uso in.

También puedes usar

my_dict.get('key', default_value)

pero me parece menos legible.


4
2017-08-01 21:32



Si tienes algo como esto

t.has_key(ew)

cámbielo a continuación para ejecutar en Python 3.X y superior

key = ew
if key not in t

4
2018-01-24 00:21