2012-07-09 16 views
6

Duplicar posibles:
'has_key()' or 'in'?diferencia entre eficiencia y dict.has_key clave en dict en Python

En Python, hay dos maneras de decidir si un key está en un dict :

if dict.has_key(key) y if key in dict

Alguien me dice que el segundo es más lento que el primero ya que la palabra clave in hace que la expresión sea una iteración sobre el dict, por lo que será más lenta que la alternativa has_key, que aparentemente usa hash para tomar la decisión.

Como dudo mucho de la diferencia, ya que creo que Python es lo suficientemente inteligente como para traducir una palabra clave in ante un dict de alguna manera hash, no puedo encontrar ningún reclamo formal sobre esto.

¿Existe realmente alguna diferencia de eficiencia entre los dos?

Gracias.

Respuesta

8

Ambas operaciones hacen lo mismo: examine la tabla hash implementada en el dict para la clave. Ninguno repetirá el diccionario completo. Tenga en cuenta que for x in dict es diferente de if x in dict. Ambos usan la palabra clave in, pero son operaciones diferentes.

La palabra clave in se convierte en una llamada en dict.__contains__, que dict puede implementar como quiera.

Si hay una diferencia en los tiempos de estas operaciones, será muy pequeña, y tendrá que ver con la sobrecarga de llamada de función de has_key.

Por cierto, la preferencia general es key in dict como una expresión más clara de la intención que dict.has_key(key). Tenga en cuenta que la velocidad no tiene nada que ver con la preferencia. La legibilidad es más importante que la velocidad a menos que sepa que se encuentra en la ruta crítica.

+2

.... todo esto y, además, 'has_key()' está en desuso y ya no se debe usar. :) – jonesy

3

D.has_key en realidad es más lento debido a la llamada de función:

>>> D = dict((x, y) for x, y in zip(range(1000000), range(1000000))) 
>>> from timeit import Timer 
>>> t = Timer("1700 in D", "from __main__ import D") 
>>> t.timeit() 
0.10631704330444336 
>>> t = Timer("D.has_key(1700)", "from __main__ import D") 
>>> t.timeit() 
0.18113207817077637 
+1

¿Eso es "levemente"? –

+0

Bueno, teniendo en cuenta que timeit ejecuta el enunciado un millón de veces, y el número es en segundos, la diferencia de tiempo * absoluta * es bastante pequeña – jterrace

+0

Algo así como 80 nanosegundos .. – jterrace

3

has_key no es una alternativa. Está desaprobado. No lo uses (En cualquier caso, es más lento)

Cuestiones relacionadas