dict()和{}有什么区别?

2024-06-16 08:23:50 发布

您现在位置:Python中文网/ 问答频道 /正文

所以假设我想编一本字典。我们称之为d。但是有多种方法可以用Python初始化字典!例如,我可以这样做:

d = {'hash': 'bang', 'slash': 'dot'}

或者我可以这样做:

d = dict(hash='bang', slash='dot')

或者这个,奇怪的是:

d = dict({'hash': 'bang', 'slash': 'dot'})

或者这个:

d = dict([['hash', 'bang'], ['slash', 'dot']])

还有其他许多使用dict()函数的方法。很明显,dict()提供的功能之一就是语法和初始化的灵活性。但这不是我要问的。

假设我要把d变成一本空字典。当我做d = {}而不是d = dict()时,Python解释器的幕后发生了什么?这仅仅是做同一件事的两种方法吗?使用{}是否有dict()的附加调用?一个比另一个有更多(甚至可以忽略不计)的开销吗?虽然这个问题真的完全不重要,但我很想回答这个问题。


Tags: 方法函数功能字典语法hash解释器dot
3条回答
>>> def f():
...     return {'a' : 1, 'b' : 2}
... 
>>> def g():
...     return dict(a=1, b=2)
... 
>>> g()
{'a': 1, 'b': 2}
>>> f()
{'a': 1, 'b': 2}
>>> import dis
>>> dis.dis(f)
  2           0 BUILD_MAP                0
              3 DUP_TOP             
              4 LOAD_CONST               1 ('a')
              7 LOAD_CONST               2 (1)
             10 ROT_THREE           
             11 STORE_SUBSCR        
             12 DUP_TOP             
             13 LOAD_CONST               3 ('b')
             16 LOAD_CONST               4 (2)
             19 ROT_THREE           
             20 STORE_SUBSCR        
             21 RETURN_VALUE        
>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (dict)
              3 LOAD_CONST               1 ('a')
              6 LOAD_CONST               2 (1)
              9 LOAD_CONST               3 ('b')
             12 LOAD_CONST               4 (2)
             15 CALL_FUNCTION          512
             18 RETURN_VALUE        

dict()显然是C内置的。一个真正聪明或专注的人(不是我)可以看看翻译源代码,告诉你更多。我只是想炫耀一下dis.dis。:)

就性能而言:

>>> from timeit import timeit
>>> timeit("a = {'a': 1, 'b': 2}")
0.424...
>>> timeit("a = dict(a = 1, b = 2)")
0.889...

@雅各布:分配对象的方式有区别,但不是一写就抄。Python分配一个固定大小的“free list”,在这里它可以快速地分配dictionary对象(直到填满为止)。通过{}语法(或对PyDict_New的C调用)分配的词典可以来自这个自由列表。当字典不再被引用时,它将返回到空闲列表,并且该内存块可以被重用(尽管字段首先被重置)。

第一个字典将立即返回到空闲列表,下一个字典将重用其内存空间:

>>> id({})
340160
>>> id({1: 2})
340160

如果保留引用,则下一个词典将来自下一个空闲插槽:

>>> x = {}
>>> id(x)
340160
>>> id({})
340016

但我们可以删除对该词典的引用并再次释放它的槽:

>>> del x
>>> id({})
340160

由于{}语法是用字节码处理的,因此可以使用上述优化。另一方面,dict()的处理就像一个普通的类构造函数,而Python使用通用内存分配器,它不遵循像上面的空闲列表那样容易预测的模式。

另外,从Python2.6的compile.c看,使用{}语法,它似乎可以根据在解析时已知的存储项的数量预先调整哈希表的大小。

相关问题 更多 >