Python 列表与带连接函数的生成器理解速度

Python 列表与带连接函数的生成器理解速度,python,python-2.7,list-comprehension,Python,Python 2.7,List Comprehension,所以我从官方文件中得到了这些例子。 究竟是什么使第一个示例(生成器表达式)比第二个示例(列表理解)慢 如果iterable参数不是列表或元组,则str.join方法将其iterable参数转换为列表。这允许连接逻辑在项目上迭代多次(它进行一次传递以计算结果字符串的大小,然后进行第二次传递以实际复制数据) 您可以在以下内容中看到这一点: C API中的PySequence\u Fast函数正是我所描述的。它将任意iterable转换为一个列表(基本上是通过对其调用list),除非它已经是一个列表

所以我从官方文件中得到了这些例子。

究竟是什么使第一个示例(生成器表达式)比第二个示例(列表理解)慢


如果iterable参数不是列表或元组,则
str.join
方法将其iterable参数转换为列表。这允许连接逻辑在项目上迭代多次(它进行一次传递以计算结果字符串的大小,然后进行第二次传递以实际复制数据)

您可以在以下内容中看到这一点:

C API中的
PySequence\u Fast
函数正是我所描述的。它将任意iterable转换为一个列表(基本上是通过对其调用
list
),除非它已经是一个列表或元组


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

请参见Ray Hettinger在这里的回答@BhargavRao——虽然我同意Raymond的回答确实解决了这个问题,但这个问题与那个问题根本不同。(这里,OP想知道为什么列表比较快——在另一个问题中,OP甚至不知道生成器和列表比较之间的区别…)。我想我不确定在这样的情况下,应该采取什么样的政策来打击受骗者…@mgilson另一个问题是这个问题的超集。meta上有一篇帖子说,我们可以投票结束一个更广泛问题的重复。例如,如何将其转换为列表理解,作为列表comp的副本,它是如何工作的。有人试图提出更广泛的问题来帮助老年退休金计划(看看)。总而言之,如果某个问题在其他地方得到了回答,那么我们就完蛋了。(我反对“为锤子而不是普通的锤子制作复制品”有答案的说法)如果需要的话,我们可以将其作为复制品重新关闭,而复制品又是原始帖子的复制品。
>>> 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
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");

    /* ... */
}