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ó.

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top