2015-09-08 86 views
10

join()函数接受可迭代的参数。不过,我想知道为什么有:Python:理解迭代器和`join()`更好

text = 'asdfqwer' 

此:

''.join([c for c in text]) 

显著快于:

''.join(c for c in text) 

同样对长字符串时(即text * 10000000)。

用长字符串观察两个执行的内存占用情况,我认为它们都在内存中创建了一个且只有一个字符的列表,然后将它们连接成一个字符串。所以我猜测,差别只在于join()如何从生成器中创建这个列表,以及Python解释器在看到[c for c in text]时是如何做同样的事情。但是,我只是在猜测,所以我希望有人确认/否认我的猜测。

+0

@AvinashRaj:你在哪里看到一个元组? – Matthias

+0

@Matthias ya,错误地提到了元组而不是生成器。 –

+0

大概你指的是:http://stackoverflow.com/a/9061024/3001761 – jonrsharpe

回答

10

join方法读取其输入两次;一次确定为结果字符串对象分配多少内存,然后再次执行实际的连接。传递一个列表比传递一个生成器对象更快,它需要创建一个副本,以便它可以遍历它两次。

列表理解不仅仅是一个包含在列表中的生成器对象,因此从外部构造列表比从生成器对象创建列表更快。发生器对象针对内存效率进行了优化,而非速度。

当然,一个字符串是已经是一个可迭代的对象,所以你可以只写''.join(text)。 (这也不像从字符串明确创建列表那么快)。

+0

我刚刚用一台可以打印的发生器进行测试。 'join'没有执行两次发生器。这是一个相当牵强的主张。是什么让你认为它执行发生器两次? –

+1

@DanielDarabos *“它需要复制一份”* - 将它消耗到列表中! – jonrsharpe

+2

由于您在回答中提到它,因此重现了我的问题评论:有趣的是,我的系统上的'timeit'显示列表比这里的直接字符串迭代更快。 –