2017-05-05 64 views
1

是没有任何理由的内存,速度或什么的,我会想使用:的Python的3.x的列表理解VS元组发电机

tuple(i for i in range(5000)) 

代替:

[i for i in range(5000)] 

如果我没不介意元组的不变性

+1

如果需要元组,请使用前者(或'list(range(5000) )')如果你需要一个列表。 – vaultah

+0

“tuple”或“list”之间的选择取决于您计划使用它而不是资源。 –

+0

除了转换的开销之外,元组将更小更快,因为它缺乏使其变得可变的机制,允许快速插入等。但是转换过程需要额外的时间(一次)。 –

回答

2

基本上,列表理解比生成器表达式更快,原因在于 其迭代在C中执行 (阅读@Vee德拉克对此的评论)。但是在元组中使用生成器表达式的唯一原因是您希望对项目执行一些操作和/或对它们进行过滤,更重要的是您需要一个元组(因为不可变性及其对可变对象的好处)。

毕竟可以随时timeit代码:

In [10]: %timeit tuple(i for i in range(5000)) 
1000 loops, best of 3: 325 µs per loop 

In [11]: %timeit [i for i in range(5000)] 
1000 loops, best of 3: 199 µs per loop 

另外请注意,正如我所说,如果你想使用内涵,你必须需要对您的项目进行操作,否则你可以直接调用函数在你的迭代器,这是更快:

In [12]: %timeit list(range(5000)) 
10000 loops, best of 3: 98.3 µs per loop 
+0

“它的迭代在C中执行”→这是关于Python的最普遍的,完全错误的神话之一。列表理解速度更快,因为暂停和恢复函数的框架很慢,而不是因为对列表理解有特别的要求。 – Veedrac

+0

@Veedrac你有任何可靠的资源吗?因为,据我记忆,很久以前我已经阅读了Mark Lutz Learning Python的书。如果不是这样的话(现在我认为你更可能是对的),不仅如此,还有其他可能提及这种说法的着名资源需要一个严肃的批评。 – Kasramvd

+0

我可以通过代码编译这个代码(我甚至贡献了部分代码),但目前在Google上找不到任何参考。我知道他们的存在是因为我以前写过这篇文章,但是我的Google-fu却让我失望。 – Veedrac

1

生成器表达式(或genexps,简称)在循环最好用于处理大量的数据时节省内存。将genexp扩展为可重用的数据类型(例如列表,元组,集合)并不被认为是好的做法。

另外请记住,Python 3中的range()与Python 2中的xrange()类似,它返回一个生成器。实际上,即使对于5000,xrange()也会更快。注意:Python 3中不存在xrange()。