使用dict文字和dict构造函数之间有区别吗?

mal*_*ree 192 python dictionary pycharm

使用PyCharm,我注意到它提供转换dict文字:

d = {
    'one': '1',
    'two': '2',
}
Run Code Online (Sandbox Code Playgroud)

进入一个dict构造函数:

d = dict(one='1', two='2')
Run Code Online (Sandbox Code Playgroud)

这些不同的方法在某些重要方面有所不同吗?

(在写这个问题时,我注意到使用dict()它似乎不可能指定一个数字键.. d = {1: 'one', 2: 'two'}是可能的,但显然,dict(1='one' ...)不是.还有其他吗?)

Joh*_*ooy 111

我想你已经指出了最明显的区别.除此之外,

第一个不需要查找dict哪个应该使它更快一点

第二查找dictlocals(),然后globals()和出土文物内置的,所以你可以通过定义一个本地被叫交换机的行为dict,例如,虽然我想不出任何地方调试的时候,这将是一个好主意,除了可能

  • 本地调用dict可能有用的示例:http://stackoverflow.com/a/7880276/313113 (4认同)

Dan*_*uev 54

Literal更快,因为它使用优化的BUILD_MAP和STORE_MAP操作码而不是通用的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
Run Code Online (Sandbox Code Playgroud)

  • @Ned它在一个线程中是相关的,询问哪一个更快. (28认同)
  • @Ned:大多数的时间不会在所有问题,但也有地方正在创建百万或数十亿的这些和2倍的速度提升是有意义的情况下,大多数用户. (10认同)
  • @Elliot OP没有问哪一个更快. (9认同)
  • @MrFooz:有类似的情况.我想你会发现99.9%做微观时间的人不在这种情况下. (5认同)
  • @JesseTaylor 在真实的程序中,这种差异不太可能很大。它的速度“快了一倍”,但也只快了半微秒。 (2认同)
  • 如果您正在生成数百万个词组或一个带有数百万个键的词典,那么从源代码中的字典文字来看,你做错了. (2认同)

Pao*_*tti 39

它们在Python 3.2上看起来几乎相同.

正如gnibbler指出的那样,第一个不需要查找dict,这应该会使它更快一点.

>>> 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
Run Code Online (Sandbox Code Playgroud)


Ned*_*der 13

这两种方法产生相同的字典,正如您所指出的那样,Python的词法规则会干扰.

字典文字是一个更明显的字典,你可以创建任何类型的键,但你需要引用键名.另一方面,如果出于某种原因需要,可以使用变量作为键:

a = "hello"
d = {
    a: 'hi'
    }
Run Code Online (Sandbox Code Playgroud)

dict()构造给你因为各种输入的形式它需要更多的灵活性.例如,您可以为它提供成对的迭代器,并将它们视为键/值对.

我不知道为什么PyCharm会提供将一个表单转换为另一个表单的原因.

  • 好吧,我猜PyCharm只是想要更好.正如它总是似乎提供将单引号字符串转换为双引号 - 没有明显的原因. (2认同)

小智 7

与python 3.4 + pycharm的一个重要区别是,如果键的数量超过256,则dict()构造函数会产生"语法错误"消息.

我现在更喜欢使用dict文字.

  • 它不仅仅是python 3.4.这是因为CPython <3.7具有传递给callable的最大255个文字参数.(/sf/answers/625252281/) (3认同)

Art*_*nka 6

从python 2.7教程:

一对大括号创建一个空字典:{}.在括号内放置以逗号分隔的键:值对列表,将初始键:值对添加到字典中; 这也是字典在输出上的写法.

tel = {'jack': 4098, 'sape': 4139}
data = {k:v for k,v in zip(xrange(10), xrange(10,20))}
Run Code Online (Sandbox Code Playgroud)

而:

dict()构造函数直接从存储为元组的键值对列表构建字典.当对形成模式时,列表推导可以紧凑地指定键值列表.

tel = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'jack': 4098, 'guido': 4127}
data = dict((k,v) for k,v in zip(xrange(10), xrange(10,20)))
Run Code Online (Sandbox Code Playgroud)

当键是简单字符串时,有时使用关键字参数指定对更容易:

dict(sape=4139, guido=4127, jack=4098)
>>>  {'sape': 4139, 'jack':4098, 'guido': 4127}
Run Code Online (Sandbox Code Playgroud)

所以{}和dict()都生成字典,但提供了一些不同的字典数据初始化方式.