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. Thi开发者_StackOverflow社区s 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?
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
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',
)
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.
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)
I think the first option is better because you are going to access the values as a['a'] or a['another']. The keys in your dictionary are strings, and there is no reason to pretend they are not. To me the keyword syntax looks clever at first, but obscure at a second look. This only makes sense to me if you are working with __dict__
, and the keywords are going to become attributes later, something like that.
FYI, in case you need to add attributes to your dictionary (things that are attached to the dictionary, but are not one of the keys), then you'll need the second form. In that case, you can initialize your dictionary with keys having arbitrary characters, one at a time, like so:
class mydict(dict): pass
a = mydict()
a["b=c"] = 'value'
a.test = False
Sometimes dict()
is a good choice:
a=dict(zip(['Mon','Tue','Wed','Thu','Fri'], [x for x in range(1, 6)]))
精彩评论