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

发布于 2024-11-19 01:29:15 字数 428 浏览 2 评论 0原文

使用 PyCharm,我注意到它可以转换字典文字

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

进入字典构造函数

d = dict(one='1', two='2')

这些不同的方法是否在某些方面存在显着差异?

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

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

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

into a dict constructor:

d = dict(one='1', two='2')

Do these different approaches differ in some significant way?

(While writing this question I noticed that using dict() it seems impossible to specify a numeric key .. d = {1: 'one', 2: 'two'} is possible, but, obviously, dict(1='one' ...) is not. Anything else?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

吝吻 2024-11-26 01:29:15

我认为你已经指出了最明显的区别。除此之外,

第一个不需要查找 dict 这应该会使

第二个在 locals() 中查找 dict 快一点> 然后 globals() 并找到内置函数,因此您可以通过定义一个名为 dict 的本地来切换行为,例如,尽管我想不出任何地方可以这样做除了调试时可能是个好主意

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

相思碎 2024-11-26 01:29:15

文字速度要快得多,因为它使用优化的 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

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
祁梦 2024-11-26 01:29:15

它们在 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

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
魔法唧唧 2024-11-26 01:29:15

这两种方法生成相同的字典,除了 Python 的词法规则干扰之外,正如您所指出的。

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

a = "hello"
d = {
    a: 'hi'
    }

dict() 构造函数为您提供了更大的灵活性,因为它采用多种形式的输入。例如,您可以为它提供一个对的迭代器,它会将它们视为键/值对。

我不知道为什么 PyCharm 会提供将一种形式转换为另一种形式的功能。

These two approaches produce identical dictionaries, except, as you've noted, where the lexical rules of Python interfere.

Dictionary literals are a little more obviously dictionaries, and you can create any kind of key, but you need to quote the key names. On the other hand, you can use variables for keys if you need to for some reason:

a = "hello"
d = {
    a: 'hi'
    }

The dict() constructor gives you more flexibility because of the variety of forms of input it takes. For example, you can provide it with an iterator of pairs, and it will treat them as key/value pairs.

I have no idea why PyCharm would offer to convert one form to the other.

云胡 2024-11-26 01:29:15

与 python 3.4 + pycharm 的一大区别是 dict() 构造函数
如果键的数量超过 256,则会生成“语法错误”消息。

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

One big difference with python 3.4 + pycharm is that the dict() constructor
produces a "syntax error" message if the number of keys exceeds 256.

I prefer using the dict literal now.

零度℉ 2024-11-26 01:29:15

来自 python 2.7 教程:

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

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

尽管:

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)))

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

dict(sape=4139, guido=4127, jack=4098)
>>>  {'sape': 4139, 'jack':4098, 'guido': 4127}

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

From python 2.7 tutorial:

A pair of braces creates an empty
dictionary: {}. Placing a
comma-separated list of key:value
pairs within the braces adds initial
key:value pairs to the dictionary;
this is also the way dictionaries are
written on output.

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

While:

The dict() constructor builds
dictionaries directly from lists of
key-value pairs stored as tuples. When
the pairs form a pattern, list
comprehensions can compactly specify
the key-value list.

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)))

When the keys are simple strings, it
is sometimes easier to specify pairs
using keyword arguments:

dict(sape=4139, guido=4127, jack=4098)
>>>  {'sape': 4139, 'jack':4098, 'guido': 4127}

So both {} and dict() produce dictionary but provide a bit different ways of dictionary data initialization.

潇烟暮雨 2024-11-26 01:29:15

当你从其他东西(非Python)复制粘贴值时,dict()文字是很好的
例如环境变量列表。
如果您有一个 bash 文件,那么

FOO='bar'
CABBAGE='good'

您可以轻松地将其粘贴到 dict() 文字中并添加注释。它还可以更轻松地执行相反的操作,即复制到其他内容中。而 {'FOO': 'bar'} 语法对于 python 和 json 来说非常独特。因此,如果您经常使用 json,您可能需要使用带双引号的 {} 文字。

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.

紫瑟鸿黎 2024-11-26 01:29:15

我发现字典文字 d = {'one': '1'} 更具可读性,您的定义数据,而不是分配事物值并将它们发送到 dict()< /代码> 构造函数。

另一方面,我看到人们将 dict 文字错误地输入为 d = {'one', '1'} ,这在现代 python 2.7+ 中将创建一个集合。

尽管如此,我仍然更喜欢使用集合文字,因为我认为它更具可读性,我认为是个人偏好。

I find the dict literal d = {'one': '1'} to be much more readable, your defining data, rather than assigning things values and sending them to the dict() constructor.

On the other hand i have seen people mistype the dict literal as d = {'one', '1'} which in modern python 2.7+ will create a set.

Despite this i still prefer to all-ways use the set literal because i think its more readable, personal preference i suppose.

︶葆Ⅱㄣ 2024-11-26 01:29:15

撇开性能不谈(因为性能差异不大),当​​字典用于传递关键字参数时,我使用 dict 函数。这样,它可以确保您在 dict 中输入的任何内容都是关键字参数的有效键,它不能以数字开头,不能包含特殊字符等。

例如:

def foo(a=0, b=0):
    return a + b

def bar(a=0, b=0):
    return a - b

def apply(funcs, kwargs):
    return [func(**kwargs) for func in funcs]

>>> apply([foo, bar], dict(a=10, b=20))
[30, -10]

Performance aside (since the performance difference isn't much), I use the dict function for when the dictionary is intended for passing keyword arguments. This way, it ensures whatever you put in the dict is a valid key for a keyword argument, it cannot start with a number, cannot contain special characters, etc.

For example:

def foo(a=0, b=0):
    return a + b

def bar(a=0, b=0):
    return a - b

def apply(funcs, kwargs):
    return [func(**kwargs) for func in funcs]

>>> apply([foo, bar], dict(a=10, b=20))
[30, -10]
剧终人散尽 2024-11-26 01:29:15

没有字典文字来创建字典继承类、具有附加方法的自定义字典类。在这种情况下,应使用自定义 dict 类构造函数,例如:

class NestedDict(dict):

    # ... skipped

state_type_map = NestedDict(**{
    'owns': 'Another',
    'uses': 'Another',
})

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',
})
走过海棠暮 2024-11-26 01:29:15

在这里聚会已经太晚了,但是如果你有一个 kwargs 函数:

def foo(a=None, b=None):
    ...

并且你像这样泼洒 dict

d_1 = { 'a': 1, 'b': 2 }
d_2 = dict(a=1, b=2)

# This works
foo(**d_1)

# And this as well
foo(**d_2)

但是 d_2 可能更适合重构可能会改变的参数名称在您的 foo 签名中。因为在 d_1 中它们是字符串。

Super late to the party here, but if you have a kwargs function:

def foo(a=None, b=None):
    ...

And your splatting a dict like so:

d_1 = { 'a': 1, 'b': 2 }
d_2 = dict(a=1, b=2)

# This works
foo(**d_1)

# And this as well
foo(**d_2)

But d_2 may be better suited for refactoring argument names that may change in your foo signature. Since in d_1 they are strings.

缱倦旧时光 2024-11-26 01:29:15

另外,当谈到阅读代码(很多)时,我觉得文字的认知负担更小(因为我们将文字与比 dict() 更不“活跃”的东西联系起来) > 与 dict() 相比,它看起来像是一个函数调用,让大脑感到好奇......至少有一微秒:)),不可否认,部分原因是编辑器中的语法突出显示,但在日常工作中仍然非常相关(至少对我来说)。

如果我专注于表示为 ... 的 dict 语句周围的代码,文字字典会让我更容易理解周围的代码:)。

...
...
...
config = {
    'key1':"value1",
    'key2':"value2",
    'key3':"value3",
    'key4':"value4",
}
...
...
...

#****VS *****

...
...
...
config =dict(
    key1 = 'value1',
    key2 = 'value2',
    key3 = 'value3',
    key4 = 'value4',

)
...
...
...

Also, when it comes to reading code (which is a lot), I feel that the literal has less cognitive burden (because we associate literals to be something that is less "active" than say a dict() which looks like a function call which makes the brain wonder...at least for a micro second :)) compared to dict(), admittedly partly due to the syntax highlighting in the editor, but still very relevant on a daily basis (at least for me).

If I focus on the surrounding code around the dict statement represented as ..., a literal dict makes it a bit easier for me to understand the surrounding code :).

...
...
...
config = {
    'key1':"value1",
    'key2':"value2",
    'key3':"value3",
    'key4':"value4",
}
...
...
...

#****VS *****

...
...
...
config =dict(
    key1 = 'value1',
    key2 = 'value2',
    key3 = 'value3',
    key4 = 'value4',

)
...
...
...

眸中客 2024-11-26 01:29:15

还要考虑这样一个事实,即与运算符匹配的标记不能在构造函数语法中使用,即破折号键。

>>> dict(foo-bar=1)
File "<stdin>", line 1
SyntaxError: keyword can't be an expression

>>> {'foo-bar': 1}
{'foo-bar': 1}

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}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文