Is there a difference between using a dict literal and a dict constructor?
使用pycharm,我注意到它提供了转换dict文本的功能:
1 2 3 4 | d = { 'one': '1', 'two': '2', } |
到dict构造函数中:
1 | d = dict(one='1', two='2') |
这些不同的方法有什么显著的区别吗?
(在写这个问题的时候,我注意到使用
我想你已经指出了最明显的区别。除此之外,
第一个不需要查找
第二种方法是在
文字速度更快,因为它使用优化的构建映射和存储映射操作码,而不是通用的调用函数:
1 2 3 4 5 6 7 8 9 10 11 | > 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 |
它们在python3.2上看起来几乎是一样的。
正如Gnibbler指出的,第一个不需要查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | >>> 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 |
这两种方法产生相同的字典,正如您所指出的,除了Python的词汇规则会干扰的地方。
字典文本是一个更明显的字典,您可以创建任何类型的键,但您需要引用键名。另一方面,如果出于某种原因需要,可以将变量用于键:
1 2 3 4 | a ="hello" d = { a: 'hi' } |
我不知道为什么Pycharm会提出将一种形式转换为另一种形式。
与python3.4+pycharm的一大区别是dict()构造函数如果键数超过256,则生成"语法错误"消息。
我现在更喜欢使用dict文字。
从python 2.7教程:
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.
1 2 | tel = {'jack': 4098, 'sape': 4139} data = {k:v for k,v in zip(xrange(10), xrange(10,20))} |
而:
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.
1 2 | 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:
1 2 | dict(sape=4139, guido=4127, jack=4098) >>> {'sape': 4139, 'jack':4098, 'guido': 4127} |
因此,和dict()都生成字典,但提供了一些不同的字典数据初始化方法。
没有用于创建dict继承类的dict文本,也没有用于使用其他方法创建自定义dict类的dict文本。在这种情况下,应使用自定义dict类构造函数,例如:
1 2 3 4 5 6 7 8 | class NestedDict(dict): # ... skipped state_type_map = NestedDict(**{ 'owns': 'Another', 'uses': 'Another', }) |
我发现dict-literal
另一方面,我看到人们把dict文本错误地输入为
尽管如此,我仍然倾向于所有方式使用set-literal,因为我认为它更具可读性,我想是个人偏好。
另外,还要考虑这样一个事实:与运算符匹配的标记不能在构造函数语法中使用,即dasherized键。
1 2 3 4 5 6 | >>> dict(foo-bar=1) File"<stdin>", line 1 SyntaxError: keyword can't be an expression >>> {'foo-bar': 1} {'foo-bar': 1} |
当您从其他对象(非python)复制粘贴值时,dict()文本很好。例如环境变量列表。如果你有bash文件,就说
1 2 | FOO='bar' CABBAGE='good' |
您可以很容易地将其粘贴到