What is the preferred syntax for initializing a dict: curly brace literals {} or the dict() function?
I'm putting in some effort to learn Python, and I am paying close attention to common coding standards. This may seem like a pointlessly nit-picky question, but I am trying to focus on best-practices as I learn, so I don't have to unlearn any 'bad' habits later.
I see two common methods for initializing a dict:
a = {
'a': 'value',
'another': 'value',
}
b = dict(
a='value',
another='value',
)
Which is considered to be "more pythonic"? Which do you use? Why?
Solution 1:
Curly braces. Passing keyword arguments into dict()
, though it works beautifully in a lot of scenarios, can only initialize a map if the keys are valid Python identifiers.
This works:
a = {'import': 'trade', 1: 7.8}
a = dict({'import': 'trade', 1: 7.8})
This won't work:
a = dict(import='trade', 1=7.8)
It will result in the following error:
a = dict(import='trade', 1=7.8)
^
SyntaxError: invalid syntax
Solution 2:
The first, curly braces. Otherwise, you run into consistency issues with keys that have odd characters in them, like =
.
# Works fine.
a = {
'a': 'value',
'b=c': 'value',
}
# Eeep! Breaks if trying to be consistent.
b = dict(
a='value',
b=c='value',
)
Solution 3:
The first version is preferable:
- It works for all kinds of keys, so you can, for example, say
{1: 'one', 2: 'two'}
. The second variant only works for (some) string keys. Using different kinds of syntax depending on the type of the keys would be an unnecessary inconsistency. -
It is faster:
$ 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
- If the special syntax for dictionary literals wasn't intended to be used, it probably wouldn't exist.
Solution 4:
I almost always use curly-braces; however, in some cases where I'm writing tests, I do keyword packing/unpacking, and in these cases dict() is much more maintainable, as I don't need to change:
a=1,
b=2,
to:
'a': 1,
'b': 2,
It also helps in some circumstances where I think I might want to turn it into a namedtuple or class instance at a later time.
In the implementation itself, because of my obsession with optimisation, and when I don't see a particularly huge maintainability benefit, I'll always favour curly-braces.
In tests and the implementation, I would never use dict() if there is a chance that the keys added then, or in the future, would either:
- Not always be a string
- Not only contain digits, ASCII letters and underscores
- Start with an integer (
dict(1foo=2)
raises a SyntaxError)