词典理解多种方式

Dictionary comprehension multiple ways

python中的以下两个语句有什么区别?

l = [1,2,3,4]
a = {item:0 for item in l}
b = dict((item,0) for item in l)
a == b
# True

我相信第一种是通过 PEP 的理解来初始化字典的正确方法,但第二种方法似乎只是创建一个生成器表达式,然后从中创建一个字典(也许它确实如此与幕后的第一种方法完全相同?)。两者之间究竟有什么区别,应该优先选择哪一个?

a = {item:0 for item in l}

直接构造一个dict,没有中间体

b = dict((item,0) for item in l)

为列表中的每个项目生成一个元组并将其提供给 dict() 构造函数。

如果不真正深入研究生成的 Python 字节代码的内容,我怀疑是否有一种简单的方法可以找出它们到底有何不同。在性能方面,它们也可能非常接近。

这里我主要考虑的是可读性和可维护性。第一种方式只依赖于你需要的元素,不涉及中间数据类型(元组),也不直接调用类型,而是依赖语言本身来正确地挂钩。作为奖励,它更短更简单——我看不出使用第二个选项有任何优势,除了可能明确使用 dict,告诉其他人预期的类型是什么。但是,如果他们一开始不从 {} 那里得到,我怀疑他们到底有多好...

我想我会测试速度:

from timeit import timeit
from random import randint

l = [randint(0, 1000) for _ in range(1000)]


def first():
    return {item: 0 for item in l}


def second():
    return dict((item,0) for item in l)


print(timeit(first, number=10000))
print(timeit(second, number=10000))

结果:

0.46899440000000003
1.0817516999999999

速度也始终如一,因此似乎无需使用第二个选项。如果这里有什么令人惊讶的地方,那就是第二个示例的优化程度有多差以及它的性能有多差。