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


212

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

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

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

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

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


5
您正在使用什么教程?您在哪里看到导致混乱的示例?
S.Lott

2
好吧,我一直在使用Python教程,深入研究Python,然后使用各种博客,SO帖子和其他Googled资源。官方文档使用的方式{}相当统一,但是我在dict()其他地方看到了很多明确的方法。我可以看到显式语法的好处,但是官方文档中缺少该方法使我感到怀疑。发布此内容后,我查看了库文档,dict并发现当使用显式dict变量初始化字典时,键必须为有效标识符的警告。
daotoad

2
“ dict()”比“ {}”如何更明确?我不明白你的困惑。两者在我看来似乎都很明确。您能否提供引号或参考,以使您说“ dict”是“显式”而“ {}”不是明确的?您认为这种区别从何而来?
S.Lott

21
区别是拼写。 dict()是拼写的dict-它使用类型的名称。大括号({})依靠标点符号来识别类型。
daotoad 2010年

Answers:


235

大括号。将关键字参数传递给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  ^

85

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

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

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

11
这就是为什么人们可能更喜欢使用dict()方法进行初始化的原因,它强制字典键为有效的标识符,因此它们与** kwargs兼容,并且键为有效的属性名。
RufusVS

57

第一个版本更可取:

  • 它适用于各种键,因此您可以说{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
  • 如果不打算使用字典文字的特殊语法,则可能不存在。

3

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


3

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

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

2

有时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)]))


2
有一个枚举函数可以更好地做到这一点。为此,有一个Enum类型可以更好地完成您在此处所做的事情。而且,这根本不是问题的答案。
dusktreader

2

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

a=1,
b=2,

至:

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

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

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

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

  • 并不总是一个字符串
  • 不仅包含数字,ASCII字母和下划线
  • 以整数开头(dict(1foo=2)引发SyntaxError)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.