Is there a difference between using a dict literal and a dict constructor?

前端 未结 10 2038
深忆病人
深忆病人 2020-11-28 02:26

Using PyCharm, I noticed it offers to convert a dict literal:

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

相关标签:
10条回答
  • 2020-11-28 02:32

    I think you have pointed out the most obvious difference. Apart from that,

    the first doesn't need to lookup dict which should make it a tiny bit faster

    the second looks up dict in locals() and then globals() and the finds the builtin, so you can switch the behaviour by defining a local called dict for example although I can't think of anywhere this would be a good idea apart from maybe when debugging

    0 讨论(0)
  • 2020-11-28 02:32

    the dict() literal is nice when you are copy pasting values from something else (none python) For example a list of environment variables. if you had a bash file, say

    FOO='bar'
    CABBAGE='good'
    

    you can easily paste then into a dict() literal and add comments. It also makes it easier to do the opposite, copy into something else. Whereas the {'FOO': 'bar'} syntax is pretty unique to python and json. So if you use json a lot, you might want to use {} literals with double quotes.

    0 讨论(0)
  • 2020-11-28 02:36

    There is no dict literal to create dict-inherited classes, custom dict classes with additional methods. In such case custom dict class constructor should be used, for example:

    class NestedDict(dict):
    
        # ... skipped
    
    state_type_map = NestedDict(**{
        'owns': 'Another',
        'uses': 'Another',
    })
    
    0 讨论(0)
  • 2020-11-28 02:37

    Literal is much faster, since it uses optimized BUILD_MAP and STORE_MAP opcodes rather than generic CALL_FUNCTION:

    > 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
    
    0 讨论(0)
  • 2020-11-28 02:40

    Also consider the fact that tokens that match for operators can't be used in the constructor syntax, i.e. dasherized keys.

    >>> dict(foo-bar=1)
    File "<stdin>", line 1
    SyntaxError: keyword can't be an expression
    
    >>> {'foo-bar': 1}
    {'foo-bar': 1}
    
    0 讨论(0)
  • 2020-11-28 02:46

    They look pretty much the same on Python 3.2.

    As gnibbler pointed out, the first doesn't need to lookup dict, which should make it a tiny bit faster.

    >>> 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
    
    0 讨论(0)
提交回复
热议问题