keys - python has_key method
''has_key()'' o ''in''? (13)
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
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
Definitivamente es más pitón.
De hecho, has_key()
se eliminó en Python 3.x.
Hay un ejemplo donde in
realidad mata su rendimiento.
Si utiliza in
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
regresa a una búsqueda lineal a través de __getitem__
) .
La solución es obviamente trivial:
def __contains__(self, x):
return self.has_key(x)
La API se ve como lo hace por una razón ... El uso de las API de tipo incorporado como se documenta es Pythonic ...
Normalmente deberías hacer my_dict.get(''key'', default_value)
lugar de my_dict.get(''key'') or default_value
.
La excepción sería el caso impar de reemplazar todos los valores falsos equivalentes ( 0
, ''''
, []
etc.) devueltos desde my_dict
con default_value
.
En realidad, si la intención es obtener un valor predeterminado de un dict, ¿por qué no utilizar collections.defaultdict
lugar del comando incorporado?
>>> from collections import defaultdict
>>> d42 = defaultdict(lambda: 42)
>>> d42[''x''] = 18
>>> d42[''x'']
18
>>> d42[''y'']
42
El caso de uso más común para los datos predeterminados es probablemente con el tipo de lista, por ejemplo:
>>> dl = defaultdict(list)
>>> for x, y in some_list_of_tuples:
... dl[x].append(y)
>>>
La solución para dict.has_key () está en desuso, use ''in'' - editor de texto sublime 3
Aquí he tomado 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"
Python 2.x admite has_key()
.
Python 2.3+ y Python 3.x son compatibles in
.
Python 3.x
d = {''a'': 1, ''b'': 2}
if ''a'' in d.keys():
#true condition
Según los docs python:
has_key()
está en desuso en favor de lakey in d
.
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 cheque. 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 que es menos legible.
Si tienes algo como esto
t.has_key(ew)
cámbielo a continuación para ejecutarlo en Python 3.X y superior
key = ew
if key not in t
Use dict.has_key()
si (y solo si) se requiere que su código sea ejecutable por versiones de Python anteriores a la 2.3 (cuando se introdujo la key in dict
).
gana sin problemas, no solo en elegancia (y no está en desuso ;-) sino también en rendimiento, por ejemplo:
$ 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 siempre es cierta, notará que generalmente , en Python, la solución más rápida es más elegante y Pythonic; es por eso que -mtimeit
es TAN útil - ¡no se trata solo de ahorrar cien nanosegundos aquí y allá! -)
has_key
es un método de diccionario, pero funcionará en cualquier colección, e incluso cuando __contains__
falta, utilizará cualquier otro método para iterar la colección para averiguarlo.