使用连接函数列出vs生成器理解速度

时间:2016-06-13 04:57:28

标签: python python-2.7 list-comprehension

所以我从官方文档中得到了这些例子。 https://docs.python.org/2/library/timeit.html

究竟是什么让第一个例子(生成器表达式)慢于第二个(列表推导)?

>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
0.8187260627746582
>>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000)
0.7288308143615723

1 个答案:

答案 0 :(得分:17)

str.join方法将其可迭代参数转换为列表(如果它不是列表或元组)。这使得连接逻辑可以多次遍历项目(它会通过一次计算结果字符串的大小,然后是第二次通过来实际复制数据)。

您可以在the CPython source code中看到这一点:

PyObject *
PyUnicode_Join(PyObject *separator, PyObject *seq)
{
    /* lots of variable declarations at the start of the function omitted */

    fseq = PySequence_Fast(seq, "can only join an iterable");

    /* ... */
}

C API中的PySequence_Fast函数就是我所描述的。它将任意迭代转换为列表(主要通过调用它上面的list),除非它已经是列表或元组。

将生成器表达式转换为列表意味着生成器的通常好处(较小的内存占用和可能的短路)不适用于str.join,因此(小)额外的发电机的开销使其性能变差。