问题:初始化dict的首选语法是:大括号文字{}或dict()函数?

我正在努力学习Python,并且一直密切关注通用的编码标准。这似乎是一个毫无意义的挑剔问题,但是我在学习时会尝试着眼于最佳实践,因此我不必学习任何“坏”习惯。

我看到两种初始化字典的常用方法:

a = {
    'a': 'value',
    'another': 'value',
}

b = dict( 
    a='value',
    another='value',
)

哪个被认为是“更pythonic的”?您使用哪个?为什么?

I’m putting in some effort to learn Python, and I am paying close attention to common coding standards. This may seem like a pointlessly nit-picky question, but I am trying to focus on best-practices as I learn, so I don’t have to unlearn any ‘bad’ habits.

I see two common methods for initializing a dict:

a = {
    'a': 'value',
    'another': 'value',
}

b = dict( 
    a='value',
    another='value',
)

Which is considered to be “more pythonic”? Which do you use? Why?


回答 0

大括号。将关键字参数传递给dict(),尽管它在许多情况下都能很好地工作,但只有在键是有效的Python标识符的情况下,才能初始化映射。

这有效:

a = {'import': 'trade', 1: 7.8}
a = dict({'import': 'trade', 1: 7.8})

这行不通:

a =                  dict(import='trade', 1=7.8)
>> SyntaxError: invalid syntax  ^

Curly braces. Passing keyword arguments into dict(), though it works beautifully in a lot of scenarios, can only initialize a map if the keys are valid Python identifiers.

This works:

a = {'import': 'trade', 1: 7.8}
a = dict({'import': 'trade', 1: 7.8})

This won’t work:

a =                  dict(import='trade', 1=7.8)
>> SyntaxError: invalid syntax  ^

回答 1

首先,大括号。否则,您会遇到键中包含奇数字符的一致性问题=

# Works fine.
a = {
    'a': 'value',
    'b=c': 'value',
}

# Eeep! Breaks if trying to be consistent.
b = dict( 
    a='value',
    b=c='value',
)

The first, curly braces. Otherwise, you run into consistency issues with keys that have odd characters in them, like =.

# Works fine.
a = {
    'a': 'value',
    'b=c': 'value',
}

# Eeep! Breaks if trying to be consistent.
b = dict( 
    a='value',
    b=c='value',
)

回答 2

第一个版本更可取:

  • 它适用于各种键,因此您可以说{1: 'one', 2: 'two'}。第二种变体仅适用于(某些)字符串键。根据键的类型使用不同种类的语法将是不必要的不​​一致。
  • 它更快:

    $ python -m timeit "dict(a='value', another='value')"
    1000000 loops, best of 3: 0.79 usec per loop
    $ python -m timeit "{'a': 'value','another': 'value'}"
    1000000 loops, best of 3: 0.305 usec per loop
  • 如果不打算使用字典文字的特殊语法,则可能不存在。

The first version is preferable:

  • It works for all kinds of keys, so you can, for example, say {1: 'one', 2: 'two'}. The second variant only works for (some) string keys. Using different kinds of syntax depending on the type of the keys would be an unnecessary inconsistency.
  • It is faster:

    $ python -m timeit "dict(a='value', another='value')"
    1000000 loops, best of 3: 0.79 usec per loop
    $ python -m timeit "{'a': 'value','another': 'value'}"
    1000000 loops, best of 3: 0.305 usec per loop
    
  • If the special syntax for dictionary literals wasn’t intended to be used, it probably wouldn’t exist.

回答 3

我认为第一种选择更好,因为您将以a [‘a’]或a [‘another’]的形式访问值。字典中的键是字符串,没有理由假装它们不是。对我来说,关键字语法乍一看看上去很聪明,但是第二眼看上去却很晦涩。仅当您使用时__dict__,这对我才有意义,并且关键字稍后将成为属性,诸如此类。

I think the first option is better because you are going to access the values as a[‘a’] or a[‘another’]. The keys in your dictionary are strings, and there is no reason to pretend they are not. To me the keyword syntax looks clever at first, but obscure at a second look. This only makes sense to me if you are working with __dict__, and the keywords are going to become attributes later, something like that.


回答 4

仅供参考,如果您需要向字典中添加属性(附加到字典中但不是键之一的属性),则需要第二种形式。在这种情况下,您可以使用具有任意字符的键来初始化字典,一次一次,如下所示:

    class mydict(dict): pass
    a = mydict()        
    a["b=c"] = 'value'
    a.test = False

FYI, in case you need to add attributes to your dictionary (things that are attached to the dictionary, but are not one of the keys), then you’ll need the second form. In that case, you can initialize your dictionary with keys having arbitrary characters, one at a time, like so:

    class mydict(dict): pass
    a = mydict()        
    a["b=c"] = 'value'
    a.test = False

回答 5

有时dict()是一个不错的选择:

a=dict(zip(['Mon','Tue','Wed','Thu','Fri'], [x for x in range(1, 6)]))

mydict=dict(zip(['mon','tue','wed','thu','fri','sat','sun'],

[random.randint(0,100)for x in range(0,7)]))

Sometimes dict() is a good choice:

a=dict(zip(['Mon','Tue','Wed','Thu','Fri'], [x for x in range(1, 6)]))

mydict=dict(zip(['mon','tue','wed','thu','fri','sat','sun'],

[random.randint(0,100) for x in range(0,7)]))


回答 6

我几乎总是使用花括号;但是,在某些情况下,当我编写测试时,我会使用关键字打包/拆包,在这种情况下,dict()更具可维护性,因为我不需要更改:

a=1,
b=2,

至:

'a': 1,
'b': 2,

在某些情况下,它在我认为以后可能需要将其转换为namedtuple或类实例的情况下也有帮助。

在实现本身中,由于我对优化的痴迷,并且当我没有看到特别巨大的可维护性好处时,我将始终青睐花括号。

在测试和实现中,如果在那时或将来添加的键有可能会出现以下情况,我将永远不会使用dict():

  • 并不总是一个字符串
  • 不仅包含数字,ASCII字母和下划线
  • 以整数开头(dict(1foo=2)引发SyntaxError)

I almost always use curly-braces; however, in some cases where I’m writing tests, I do keyword packing/unpacking, and in these cases dict() is much more maintainable, as I don’t need to change:

a=1,
b=2,

to:

'a': 1,
'b': 2,

It also helps in some circumstances where I think I might want to turn it into a namedtuple or class instance at a later time.

In the implementation itself, because of my obsession with optimisation, and when I don’t see a particularly huge maintainability benefit, I’ll always favour curly-braces.

In tests and the implementation, I would never use dict() if there is a chance that the keys added then, or in the future, would either:

  • Not always be a string
  • Not only contain digits, ASCII letters and underscores
  • Start with an integer (dict(1foo=2) raises a SyntaxError)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。