【问题标题】:Is there any benefit to returning a hash constructed with dict rather than just using the curly braces syntax?返回使用 dict 而不是仅使用花括号语法构造的哈希有什么好处吗?
【发布时间】:2010-12-14 00:20:45
【问题描述】:

在我读过的一些 Python 代码中,我一直注意到这段代码:

return dict(somekey=somevalue)

这对以下有什么好处吗:

return {somekey:somevalue}

我倾向于说不,因为两个对象都属于同一个dict 类型,但我可能错了。

【问题讨论】:

  • 您所说的“哈希”是什么?在 Python 中,我们称它们为 'dict's。
  • 来吧保罗,关闭strict标志:)
  • hash, checksum, strict = dict, hash, "anything goes"

标签: python hash dictionary


【解决方案1】:

它们在语义上是相同的。

dict( param=value, ... ) 表示法将您的键限制为有效的 Python 标识符的字符串。

dict( sequence-of-2-tuples ) 实际上与{} 相同。

{} 符号对键没有限制。除了它们是可散列的对象。

存在性能差异。

【讨论】:

  • dict 有一个我在这个网站上看到过的功能,但我自己并不觉得它很直观;您可以在一个语句中连接两个字典:D = dict(d1, **d2)。它很整洁但有点破,因为d2 必须只有字符串键。
  • 我相信d3 = dict(d1); d3.update(d2) 是合并两个字典的更常见、Pythonic 和更安全的方法。
【解决方案2】:

花括号是一种语法上的精巧,所以唯一的好处是可以更清楚地表达字典的结构。

【讨论】:

    【解决方案3】:

    dict(somekey=somevalue){'somekey': somevalue} 完全相同。 (那么,您的两个示例并不完全等效-在第一种情况下,键是字符串 'somekey' 作为键,而在第二种情况下,它是 somekey 的任何内容。)通常使用 dict 文字会更好,除非您正在避免输入所有引号。

    【讨论】:

      【解决方案4】:
      >>> def foo(): 返回 dict(a=1) ... >>> def bar(): 返回 {'a':1} ... >>> 导入磁盘 >>> dis.dis(foo) 1 0 LOAD_GLOBAL 0 (字典) 3 LOAD_CONST 1 ('a') 6 负载常数 2 (1) 9 CALL_FUNCTION 256 12 返回值 >>> dis.dis(bar) 1 0 构建地图 1 3 负载常数 1 (1) 6 LOAD_CONST 2 ('a') 9 商店地图 10 返回值 >>> 导入时间 >>> timeit.Timer(foo).timeit() 0.76093816757202148 >>> timeit.Timer(bar).timeit() 0.31897807121276855

      没有功能上的区别,但后者效率更高。

      【讨论】:

        【解决方案5】:

        {somekey:somevalue} 只能用作文字,它不允许在括号内进行任何循环。

        dict 采用**kwargs,这意味着您可以例如使用dict( **locals() )。当您不想输入引号和大括号时,dict(somekey=somevalue) 只是一个不错的快捷方式。

        还有第三个 dict 构造函数,dict([(key,val),(key2,val2)])。它最强大,经常与zip一起使用

        【讨论】:

        • 顺便说一句,Python 3 泛化列表推导以允许 dict(和集合)推导:即 {k:v for k, v in stuff if expr}
        【解决方案6】:

        Python 是动态的——因此您可以在任何范围内重新定义“dict”的含义,而 Python 的语法绝对是不可编程的。因此,当 Python 解析器看到花括号时,它可以得出结论,它必须构建一个 dict。 dict(..) 表达式必须始终像任何其他函数调用一样进行评估;查找名称、构建参数元组等。

        实际上,使用像 {} 花括号这样的容器字面量是最接近 Python 中静态类型声明的方法。

        我认为这影响了 Python 3 决定引入像 s = {1,2,3} 这样的集合文字。


        确实会发生程序员重新分配 python 内置函数的情况!我认为这主要是错误的,并且主要限于局部变量(并且 Python 的命名空间确保它不会造成太大的伤害!)Here is a Google Code Search for code reassigning dict。我认为最奇怪的例子是dict = dict();到那时,你在做什么应该很明显了!

        可以做到这一点并不意味着你应该这样做。是的,例如认为 dict 应该在 python 中真正被称为 hash 并换出另一个名为 hash 的内置函数不是你应该做的:

        hash, checksum = dict, hash
        

        :-)

        在 Python 标准库中可以找到执行此操作的代码示例。没错,这里来自 shelve.py 的第 92 行:

        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 = {}
        

        这是一个非常典型的例子; dict 用作​​方法参数,没有人注意到它并没有害处,因为方法很短。我的建议是使用内置语法突出显示来捕捉这一点。

        【讨论】:

        • +1 将 Python 的动态性作为一个理由。另一方面,虽然它是合法的,但重新定义 dict 会相当疯狂——它会破坏 Psyco,更不用说让其他使用你的代码的人感到困惑了。
        猜你喜欢
        • 2014-10-02
        • 1970-01-01
        • 2012-08-04
        • 1970-01-01
        • 2012-09-02
        • 2018-05-26
        • 2011-01-08
        • 1970-01-01
        相关资源
        最近更新 更多