keys - python dictionary of dictionaries
Diferencia entre dict.clear() y asignar{} en Python (8)
Además de la respuesta de @odano, parece que usar d.clear()
es más rápido si quieres eliminar el dict muchas veces.
import timeit
p1 = ''''''
d = {}
for i in xrange(1000):
d[i] = i * i
for j in xrange(100):
d = {}
for i in xrange(1000):
d[i] = i * i
''''''
p2 = ''''''
d = {}
for i in xrange(1000):
d[i] = i * i
for j in xrange(100):
d.clear()
for i in xrange(1000):
d[i] = i * i
''''''
print timeit.timeit(p1, number=1000)
print timeit.timeit(p2, number=1000)
El resultado es:
20.0367929935
19.6444659233
En Python, ¿hay alguna diferencia entre llamar a clear()
y asignar {}
a un diccionario? ¿Y si si, que? Ejemplo:
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
Además de las diferencias mencionadas en otras respuestas, también hay una diferencia de velocidad. d = {} es más del doble de rápido:
python -m timeit -s "d = {}" "for i in xrange(500000): d.clear()"
10 loops, best of 3: 127 msec per loop
python -m timeit -s "d = {}" "for i in xrange(500000): d = {}"
10 loops, best of 3: 53.6 msec per loop
Además, a veces la instancia dict podría ser una subclase de dict ( defaultdict
por ejemplo). En ese caso, se prefiere usar clear
, ya que no tenemos que recordar el tipo exacto de dict, y también evitar el código duplicado (acoplar la línea de compensación con la línea de inicialización).
x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)
Como ilustración de las cosas ya mencionadas anteriormente:
>>> a = {1:2}
>>> id(a)
3073677212L
>>> a.clear()
>>> id(a)
3073677212L
>>> a = {}
>>> id(a)
3073675716L
Si tiene otra variable que también hace referencia al mismo diccionario, existe una gran diferencia:
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d = {}
>>> d2
{''stuff'': ''things''}
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d.clear()
>>> d2
{}
Esto se debe a que al asignar d = {}
crea un nuevo diccionario vacío y se lo asigna a la variable d
. Esto deja a d2
apuntando al viejo diccionario con los elementos que todavía están en él. Sin embargo, d.clear()
borra el mismo diccionario al que apuntan d
y d2
.
Una cosa que no se menciona es el alcance de los problemas. No es un gran ejemplo, pero aquí está el caso en que encontré el problema:
def conf_decorator(dec):
"""Enables behavior like this:
@threaded
def f(): ...
or
@threaded(thread=KThread)
def f(): ...
(assuming threaded is wrapped with this function.)
Sends any accumulated kwargs to threaded.
"""
c_kwargs = {}
@wraps(dec)
def wrapped(f=None, **kwargs):
if f:
r = dec(f, **c_kwargs)
c_kwargs = {}
return r
else:
c_kwargs.update(kwargs) #<- UnboundLocalError: local variable ''c_kwargs'' referenced before assignment
return wrapped
return wrapped
La solución es reemplazar c_kwargs = {}
con c_kwargs.clear()
Si alguien piensa en un ejemplo más práctico, siéntete libre de editar esta publicación.
d = {}
creará una nueva instancia para d
pero todas las demás referencias seguirán apuntando a los contenidos anteriores. d.clear()
restablecerá el contenido, pero todas las referencias a la misma instancia seguirán siendo correctas.
Los métodos de mutación siempre son útiles si el objeto original no está dentro del alcance:
def fun(d):
d.clear()
d["b"] = 2
d={"a": 2}
fun(d)
d # {''b'': 2}
La reasignación del diccionario crearía un nuevo objeto y no modificaría el original.