¿Cuál es la sintaxis preferida para inicializar un dict: literales de llaves {} o la función dict()?

5 minutos de lectura

avatar de usuario
daotoad

Me esfuerzo un poco por aprender Python y presto mucha atención a los estándares de codificación comunes. Esto puede parecer una pregunta quisquillosa sin sentido, pero estoy tratando de concentrarme en las mejores prácticas a medida que aprendo, para no tener que desaprender ningún hábito ‘malo’ más adelante.

Veo dos métodos comunes para inicializar un dict:

a = {
    'a': 'value',
    'another': 'value',
}

b = dict( 
    a="value",
    another="value",
)

¿Cuál se considera “más pitónico”? ¿Cuál usas? ¿Por qué?

  • ¿Qué tutorial estás usando? ¿Dónde vio ejemplos que llevan a la confusión?

    – S. Lott

    18 de mayo de 2010 a las 2:41

  • Bueno, he estado usando el tutorial de Python, Inmersión en Python y luego una variedad de blogs, publicaciones de SO y otros recursos buscados en Google. Los documentos oficiales usan {} de manera bastante uniforme, pero veo mucho de lo explícito dict() acercarse a otra parte. Pude ver el beneficio de una sintaxis explícita, pero la ausencia del enfoque en los documentos oficiales me hizo sospechar. Después de publicar esto, miré los documentos de la biblioteca para dict y encontró la precaución de que las claves deben ser identificadores válidos cuando un explícito dict se utiliza para inicializar un dict.

    – daotoad

    18 de mayo de 2010 a las 4:35

  • ¿Cómo es “dict()” más explícito que “{}”? No entiendo tu confusión. Ambos me parecen explícitos. ¿Puede proporcionar una cita o referencia que le haga decir que “dict” es “explícito” y “{}” no es explícito? ¿De dónde crees que surge esta distinción?

    – S. Lott

    18 de mayo de 2010 a las 11:19

  • La distinción es la ortografía. dict() se escribe dict–utiliza el nombre del tipo. los frenos ({}) confían en la puntuación para identificar el tipo.

    – daotoad

    18 mayo 2010 a las 15:14

avatar de usuario
Wai Yip Tung

llaves rizadas. Pasar argumentos de palabras clave a dict()aunque funciona muy bien en muchos escenarios, solo puede inicializar un mapa si las claves son identificadores de Python válidos.

Esto funciona:

a = {'import': 'trade', 1: 7.8}
a = dict({'import': 'trade', 1: 7.8})

Esto no funcionará:

a = dict(import="trade", 1=7.8)

Dará como resultado el siguiente error:

    a = dict(import="trade", 1=7.8)
             ^
SyntaxError: invalid syntax

Los primeros, llaves. De lo contrario, se encontrará con problemas de coherencia con las teclas que tienen caracteres extraños, como =.

# Works fine.
a = {
    'a': 'value',
    'b=c': 'value',
}

# Eeep! Breaks if trying to be consistent.
b = dict( 
    a="value",
    b=c="value",
)

  • Esta es exactamente la razón por la que uno podría preferir el método dict() para la inicialización, obliga a que las claves del diccionario sean identificadores válidos, por lo que son compatibles, por ejemplo, con **kwargs, y las claves son nombres de atributos válidos.

    – Rufus VS

    10 de agosto de 2016 a las 15:57

avatar de usuario
stephan

Es preferible la primera versión:

  • Funciona para todo tipo de teclas, por lo que puede, por ejemplo, decir {1: 'one', 2: 'two'}. La segunda variante solo funciona para (algunas) teclas de cadena. Usar diferentes tipos de sintaxis dependiendo del tipo de claves sería una inconsistencia innecesaria.
  • Es mas rapido:

    $ python -m timeit "dict(a="value", another="value")"
    1000000 loops, best of 3: 0.79 usec per loop
    $ python -m timeit "{'a': 'value','another': 'value'}"
    1000000 loops, best of 3: 0.305 usec per loop
    
  • Si no se pretendiera usar la sintaxis especial para los literales de diccionario, probablemente no existiría.

Casi siempre uso llaves; sin embargo, en algunos casos en los que estoy escribiendo pruebas, hago el empaquetado/desempaquetado de palabras clave, y en estos casos dict() es mucho más fácil de mantener, ya que no necesito cambiar:

a=1,
b=2,

a:

'a': 1,
'b': 2,

También ayuda en algunas circunstancias en las que creo que podría querer convertirlo en una instancia de tupla o clase con nombre en un momento posterior.

En la implementación en sí, debido a mi obsesión con la optimización, y cuando no veo un beneficio de mantenibilidad particularmente grande, siempre preferiré las llaves.

En las pruebas y la implementación, nunca usaría dict() si existe la posibilidad de que las claves agregadas entonces, o en el futuro:

  • No siempre ser una cadena
  • No solo contiene dígitos, letras ASCII y guiones bajos
  • Comience con un número entero (dict(1foo=2) genera un SyntaxError)

Creo que la primera opción es mejor porque vas a acceder a los valores como un[‘a’] o un[‘another’]. Las claves en su diccionario son cadenas y no hay razón para pretender que no lo son. Para mí, la sintaxis de palabras clave parece inteligente al principio, pero oscura en una segunda mirada. Esto solo tiene sentido para mí si estás trabajando con __dict__y las palabras clave se convertirán en atributos más tarde, algo así.

avatar de usuario
Josué Richardson

Para su información, en caso de que necesite agregar atributos a su diccionario (cosas que están adjuntas al diccionario, pero que no son una de las claves), necesitará la segunda forma. En ese caso, puede inicializar su diccionario con claves que tengan caracteres arbitrarios, uno a la vez, así:

    class mydict(dict): pass
    a = mydict()        
    a["b=c"] = 'value'
    a.test = False

avatar de usuario
jpaugh

Algunas veces dict() es una buena opción:

a=dict(zip(['Mon','Tue','Wed','Thu','Fri'], [x for x in range(1, 6)]))

  • Hay una función de enumeración que podría hacer esto mejor. De hecho, hay un tipo Enum que puede hacer mejor lo que está haciendo aquí. Además, esto no es realmente una respuesta a la pregunta en absoluto.

    – viajero del crepúsculo

    29 de junio de 2016 a las 23:03

  • Igual que: {x:y for x,y in zip(['Mon','Tue','Wed','Thu','Fri'], [x for x in range(1, 6)])}

    – Vulwsztyn

    8 abr a las 17:43

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad