开发者

Is there any benefit to returning a hash constructed with dict rather than just using the curly braces syntax?

In some Python code I've r开发者_如何学JAVAead I keep noticing this code:

return dict(somekey=somevalue)

Does that have any benefit over:

return {somekey:somevalue}

I tend to say no, since both objects will belong to the same dict type, but I may be wrong.


>>> def foo(): return dict(a=1)
...
>>> def bar(): return {'a':1}
...
>>> import dis
>>> dis.dis(foo)
  1           0 LOAD_GLOBAL              0 (dict)
              3 LOAD_CONST               1 ('a')
              6 LOAD_CONST               2 (1)
              9 CALL_FUNCTION          256
             12 RETURN_VALUE
>>> dis.dis(bar)
  1           0 BUILD_MAP                1
              3 LOAD_CONST               1 (1)
              6 LOAD_CONST               2 ('a')
              9 STORE_MAP
             10 RETURN_VALUE
>>> import timeit
>>> timeit.Timer(foo).timeit()
0.76093816757202148
>>> timeit.Timer(bar).timeit()
0.31897807121276855

There is no functional difference, but the latter is more efficient.


They are semantically identical.

The dict( param=value, ... ) notation limits your keys to strings which are valid python identifiers.

The dict( sequence-of-2-tuples ) is effectively the same as {}.

The {} notation places no limits on the keys. Except that they be hashable objects.

There are performance differences.


{somekey:somevalue} can only be used as a literal, it doesn't allow any looping inside the brackets.

dict takes **kwargs, which means you can for example do dict( **locals() ). dict(somekey=somevalue) is just a nice shortcut when you don't want to type quotes and braces.

There is a third dict constructor too, dict([(key,val),(key2,val2)]). Its the most powerful and often used with zip


Python is dynamic -- so you can redefine what 'dict' means in any of your scopes, while Python's syntax is absolutely nonprogrammable. Thus the Python parser can conclude, when it sees the curly braces, that it must build a dict. A dict(..) expression must always be evaluated like any other function call; lookup the name, build argument tuple etc.

In effect, using container literals like the {} curly braces is the closest you can come to static type declarations in Python.

I think this has influenced the Python 3 decision to introduce set literals like s = {1,2,3}.


It does happen that programmers reassign python builtins! I think this is mostly by mistake, and mostly limited to local variables (and Python's namespaces make sure it can't do too much harm!) Here is a Google Code Search for code reassigning dict. I think the strangest example is dict = dict(); by that point, it should be obvious what you are doing!

That it's possible to do this doesn't mean you should do it. Yes, for example thinking that dict should really be called hash in python and swapping out the other builtin called hash is not something you should do:

hash, checksum = dict, hash

:-)

An example of code that does this is found right in the Python standard library. That's right, here is from line 92 of shelve.py:

def __init__(self, dict, protocol=None, writeback=False):
    self.dict = dict
    if protocol is None:
        protocol = 0
    self._protocol = protocol
    self.writeback = writeback
    self.cache = {}

This is a very typical example; dict is used as a method argument, and no-one notices and it does no harm, since the method is very short. Use syntax highlighting for builtins to catch this, is my suggestion.


The curly braces are a syntaxtic nicity, so the only benefit is can more clearly express the structure of the dict.


dict(somekey=somevalue) is exactly the same as {'somekey': somevalue}. (Your two examples, then, aren't quite quivalent—in the first case the key is the string 'somekey' as the key and in the second it is whatever somekey is.) It is generally nicer just to use dict literals unless you are avoiding typing all the quotes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜