¿Cuál es la diferencia entre dict() y {}?
-
21-08-2019 - |
Pregunta
Así que digamos que quiero hacer un diccionario.Vamos a llamar a d
.Pero hay varias maneras de inicializar un diccionario en Python!Por ejemplo, yo podría hacer esto:
d = {'hash': 'bang', 'slash': 'dot'}
O yo podría hacer esto:
d = dict(hash='bang', slash='dot')
O este, curiosamente:
d = dict({'hash': 'bang', 'slash': 'dot'})
O esto:
d = dict([['hash', 'bang'], ['slash', 'dot']])
Y otra multitud de formas con el dict()
la función.Así que, obviamente, una de las cosas dict()
proporciona flexibilidad en la sintaxis y la inicialización.Pero eso no es lo que estoy preguntando acerca de.
Decir que me iban a hacer d
sólo un diccionario vacío.Lo que sucede detrás de las escenas de la intérprete de Python cuando hago d = {}
frente a d = dict()
?Es simplemente dos maneras de hacer la misma cosa?¿El uso de {}
tiene la adicional llamada de dict()
?Tiene uno (incluso insignificante) más gastos que el otro?Mientras que la pregunta es, realmente, completamente sin importancia, es una curiosidad que me encantaría tener respondió.
Solución
>>> def f():
... return {'a' : 1, 'b' : 2}
...
>>> def g():
... return dict(a=1, b=2)
...
>>> g()
{'a': 1, 'b': 2}
>>> f()
{'a': 1, 'b': 2}
>>> import dis
>>> dis.dis(f)
2 0 BUILD_MAP 0
3 DUP_TOP
4 LOAD_CONST 1 ('a')
7 LOAD_CONST 2 (1)
10 ROT_THREE
11 STORE_SUBSCR
12 DUP_TOP
13 LOAD_CONST 3 ('b')
16 LOAD_CONST 4 (2)
19 ROT_THREE
20 STORE_SUBSCR
21 RETURN_VALUE
>>> dis.dis(g)
2 0 LOAD_GLOBAL 0 (dict)
3 LOAD_CONST 1 ('a')
6 LOAD_CONST 2 (1)
9 LOAD_CONST 3 ('b')
12 LOAD_CONST 4 (2)
15 CALL_FUNCTION 512
18 RETURN_VALUE
dict () aparentemente tiene algo de C incorporado. Una persona realmente inteligente o dedicada (no yo) podría mirar la fuente del intérprete y contarte más. Solo quería mostrar dis.dis. :)
Otros consejos
En cuanto al rendimiento:
>>> from timeit import timeit
>>> timeit("a = {'a': 1, 'b': 2}")
0.424...
>>> timeit("a = dict(a = 1, b = 2)")
0.889...
@Jacob: Hay una diferencia en cómo se asignan los objetos, pero no son copia en escritura. Python asigna un tamaño fijo & Quot; lista libre & Quot; donde puede asignar rápidamente objetos de diccionario (hasta que se llene). Los diccionarios asignados a través de la sintaxis {}
(o una llamada C a PyDict_New
) pueden provenir de esta lista gratuita. Cuando ya no se hace referencia al diccionario, vuelve a la lista libre y ese bloque de memoria se puede reutilizar (aunque los campos se restablecen primero).
Este primer diccionario vuelve inmediatamente a la lista libre, y el siguiente reutilizará su espacio de memoria:
>>> id({})
340160
>>> id({1: 2})
340160
Si mantiene una referencia, el próximo diccionario vendrá del siguiente espacio libre:
>>> x = {}
>>> id(x)
340160
>>> id({})
340016
Pero podemos eliminar la referencia a ese diccionario y liberar su espacio nuevamente:
>>> del x
>>> id({})
340160
Dado que la sintaxis dict()
se maneja en código de bytes, puede usar esta optimización mencionada anteriormente. Por otro lado, <=> se maneja como un constructor de clase regular y Python usa el asignador de memoria genérico, que no sigue un patrón fácilmente predecible como la lista gratuita anterior.
Además, mirando compile.c de Python 2.6, con la sintaxis <=> parece ajustar el tamaño de la tabla hash en función de la cantidad de elementos que está almacenando que se conoce en el momento del análisis.
Básicamente, {} es sintaxis y se maneja a nivel de idioma y código de bytes. dict () es solo otro incorporado con una sintaxis de inicialización más flexible. Tenga en cuenta que dict () solo se agregó en el medio de la serie 2.x.
Actualización:gracias por las respuestas.Quita la especulación acerca de copy-on-write.
Otra diferencia entre {}
y dict
es que dict
siempre asigna un nuevo diccionario (incluso si los contenidos son estáticos), mientras que {}
no siempre hacerlo (ver mgood la respuesta para cuándo y por qué):
def dict1():
return {'a':'b'}
def dict2():
return dict(a='b')
print id(dict1()), id(dict1())
print id(dict2()), id(dict2())
produce:
$ ./mumble.py 11642752 11642752 11867168 11867456
No estoy sugiriendo que usted trate de tomar ventaja de esto o no, depende de la situación particular, simplemente señalando hacia fuera.(Es también, probablemente, evidente a partir de la desmontaje si usted entiende los códigos de operación).
dict () se usa cuando desea crear un diccionario a partir de un iterable, como:
dict( generator which yields (key,value) pairs )
dict( list of (key,value) pairs )
Uso divertido:
def func(**kwargs):
for e in kwargs:
print(e)
a = 'I want to be printed'
kwargs={a:True}
func(**kwargs)
a = 'I dont want to be printed'
kwargs=dict(a=True)
func(**kwargs)
salida:
I want to be printed
a
Para crear un conjunto vacío, deberíamos usar el conjunto de palabras clave antes
es decir, set()
esto crea un conjunto vacío donde, como en los dictados, solo los corchetes de flores pueden crear un dict vacío
Vamos con un ejemplo
print isinstance({},dict)
True
print isinstance({},set)
False
print isinstance(set(),set)
True