tuple structures dictionaries dict create python pycharm

dictionaries - python structures



¿Hay alguna diferencia entre usar un dict literal y un dict constructor? (10)

Usando PyCharm, noté que ofrece convertir un dict literal :

d = { ''one'': ''1'', ''two'': ''2'', }

en un constructor dict :

d = dict(one=''1'', two=''2'')

¿Estos diferentes enfoques difieren de alguna manera significativa?

(Al escribir esta pregunta noté que al usar dict() parece imposible especificar una clave numérica. d = {1: ''one'', 2: ''two''} es posible, pero, obviamente, dict(1=''one'' ...) no es. ¿Algo más?)


Considere también el hecho de que los tokens que coinciden con los operadores no se pueden usar en la sintaxis del constructor, es decir, claves dasherized.

>>> dict(foo-bar=1) File "<stdin>", line 1 SyntaxError: keyword can''t be an expression >>> {''foo-bar'': 1} {''foo-bar'': 1}


Creo que dict literal d = {''one'': ''1''} es mucho más legible, tus datos de definición, en lugar de asignar valores a las cosas y enviarlas al constructor dict() .

Por otro lado, he visto personas que escriben mal el dict literal como d = {''one'', ''1''} que en el moderno pitón 2.7+ creará un conjunto.

A pesar de esto, todavía prefiero utilizar el conjunto literal porque creo que es más legible, preferencia personal, supongo.


Creo que has señalado la diferencia más obvia. Aparte de eso,

el primero no necesita consultar dict que debería hacerlo un poco más rápido

el segundo busca dict en locals() y luego globals() y encuentra el builtin, por lo que puedes cambiar el comportamiento definiendo un dict llamado local, por ejemplo, aunque no puedo pensar en ningún lado, esta sería una buena idea aparte de tal vez cuando se depura


Desde el tutorial de python 2.7:

Un par de llaves crea un diccionario vacío: {}. Al colocar una lista de pares clave-valor separados por comas, dentro de los corchetes se agregan los pares de clave inicial: valor al diccionario; esta es también la forma en que se escriben los diccionarios en la salida.

tel = {''jack'': 4098, ''sape'': 4139} data = {k:v for k,v in zip(xrange(10), xrange(10,20))}

Mientras:

El constructor dict () construye diccionarios directamente a partir de listas de pares clave-valor almacenados como tuplas. Cuando los pares forman un patrón, las listas de comprensión pueden especificar de forma compacta la lista de valores-clave.

tel = dict([(''sape'', 4139), (''guido'', 4127), (''jack'', 4098)]) {''sape'': 4139, ''jack'': 4098, ''guido'': 4127} data = dict((k,v) for k,v in zip(xrange(10), xrange(10,20)))

Cuando las claves son cadenas simples, a veces es más fácil especificar pares usando argumentos de palabra clave:

dict(sape=4139, guido=4127, jack=4098) >>> {''sape'': 4139, ''jack'':4098, ''guido'': 4127}

Entonces, tanto {} como dict () producen diccionario, pero proporcionan formas diferentes de inicialización de datos de diccionario.


Estos dos enfoques producen diccionarios idénticos, excepto, como ha notado, donde las reglas léxicas de Python interfieren.

Los literales de diccionario son un poco más obviamente diccionarios, y puede crear cualquier clase de clave, pero debe citar los nombres de las teclas. Por otro lado, puede usar variables para las claves si lo necesita por alguna razón:

a = "hello" d = { a: ''hi'' }

El constructor dict() le da más flexibilidad debido a la variedad de formas de entrada que toma. Por ejemplo, puede proporcionarle un iterador de pares y los tratará como pares clave / valor.

No tengo idea de por qué PyCharm ofrecería convertir una forma a la otra.


Literal es mucho más rápido, ya que utiliza códigos de operación optimizados BUILD_MAP y STORE_MAP en lugar de los CALL_FUNCTION genéricos:

> python2.7 -m timeit "d = dict(a=1, b=2, c=3, d=4, e=5)" 1000000 loops, best of 3: 0.958 usec per loop > python2.7 -m timeit "d = {''a'':1, ''b'':2, ''c'':3, ''d'':4, ''e'':5}" 1000000 loops, best of 3: 0.479 usec per loop > python3.2 -m timeit "d = dict(a=1, b=2, c=3, d=4, e=5)" 1000000 loops, best of 3: 0.975 usec per loop > python3.2 -m timeit "d = {''a'':1, ''b'':2, ''c'':3, ''d'':4, ''e'':5}" 1000000 loops, best of 3: 0.409 usec per loop


No existe un dict literal para crear clases heredadas por dict, clases dict personalizadas con métodos adicionales. En tal caso, se debe usar un constructor de clase dict personalizado, por ejemplo:

class NestedDict(dict): # ... skipped state_type_map = NestedDict(**{ ''owns'': ''Another'', ''uses'': ''Another'', })


Se ven más o menos iguales en Python 3.2.

Como señaló gnibbler, el primero no necesita buscar dict , lo que debería hacerlo un poco más rápido.

>>> def literal(): ... d = {''one'': 1, ''two'': 2} ... >>> def constructor(): ... d = dict(one=''1'', two=''2'') ... >>> import dis >>> dis.dis(literal) 2 0 BUILD_MAP 2 3 LOAD_CONST 1 (1) 6 LOAD_CONST 2 (''one'') 9 STORE_MAP 10 LOAD_CONST 3 (2) 13 LOAD_CONST 4 (''two'') 16 STORE_MAP 17 STORE_FAST 0 (d) 20 LOAD_CONST 0 (None) 23 RETURN_VALUE >>> dis.dis(constructor) 2 0 LOAD_GLOBAL 0 (dict) 3 LOAD_CONST 1 (''one'') 6 LOAD_CONST 2 (''1'') 9 LOAD_CONST 3 (''two'') 12 LOAD_CONST 4 (''2'') 15 CALL_FUNCTION 512 18 STORE_FAST 0 (d) 21 LOAD_CONST 0 (None) 24 RETURN_VALUE


Una gran diferencia con python 3.4 + pycharm es que el constructor dict () produce un mensaje de "error de sintaxis" si el número de claves supera 256.

Prefiero usar el dict literal ahora.


el literal dict () es agradable cuando está copiando valores de otra cosa (ninguna python) Por ejemplo, una lista de variables de entorno. si tuvieras un archivo bash, di

FOO=''bar'' CABBAGE=''good''

puede pegar fácilmente en un literal dict() y agregar comentarios. También hace que sea más fácil hacer lo opuesto, copiar en otra cosa. Mientras que la sintaxis {''FOO'': ''bar''} es bastante exclusiva de python y json. Entonces, si usa mucho json, puede usar {} literales con comillas dobles.