PEP 3106 建议更慢的方式?为什么?

PEP 3106 suggests slower way? Why?

最近,我不得不将字典的值转换为 Python 3.6 中的列表以及一个应该经常发生这种情况的用例。
为了成为一个好人,我想使用接近 PEP 的解决方案。现在,PEP 3106 建议

list(d.keys())

这显然工作正常 - 但是 在我的 Windows 7 机器上使用 timeit 我看到

>python -m timeit "[*{'a': 1, 'b': 2}.values()]"
1000000 loops, best of 3: 0.249 usec per loop

>python -m timeit "list({'a': 1, 'b': 2}.values())"
1000000 loops, best of 3: 0.362 usec per loop

我认为后一个版本有优势,否则 PEP 为什么要推荐较慢的版本。

所以我的问题来了:后一个版本与第一个版本相比有什么优势?

答案是因为更快的语法是在 PEP 448 in 2013, while PEP 3106 中首次引入的,您引用的是 2006 年编写的,所以即使现在确实更快,但在编写 PEP 时它并不存在。

正如其他人所指出的,PEP 的作用不是为最快的代码提供模板 - 通常,PEP 中的代码旨在尽可能简单和清晰,因为示例通常是关于理解概念的而不是获得最好的结果,所以即使当时语法确实存在,并且以真实(和可靠)的方式更快,它仍然可能没有被使用。

使用更大的值进行一些进一步测试:

python -m timeit -s "x = [1]*10000" "[*x]"                
10000 loops, best of 3: 44.6 usec per loop

python -m timeit -s "x = [1]*10000" "list(x)" 
10000 loops, best of 3: 44.8 usec per loop

显示差异并不是真正的两倍,而是固定成本 - 我猜这是查找 list() built-in 函数的成本。这在大多数实际情况下可以忽略不计。