Python 3.x列表推导式与元组生成器

7

我要翻译的内容是:“有没有任何关于内存、速度或其他方面的原因,让我想要使用以下选项:”

tuple(i for i in range(5000))

替代:

[i for i in range(5000)]

如果我不在意元组的不可变性


1
如果你需要一个元组,请使用前者;如果你需要一个列表,请使用后者(或list(range(5000)))。 - vaultah
选择使用 tuple 还是 list 取决于你打算用它来做什么,而不是资源。 - Ma0
第一个会慢一些,但最终可能需要更少的内存。 - Eli Korvigo
1
为了提高速度,您可以删除不必要的推导式;)tuple(range(5000))list(range(5000)),或者根据您的需求,只使用range(5000) - Eric Duminil
@new_to_coding 是的 - Eli Korvigo
显示剩余3条评论
2个回答

6
基本上,列表推导比生成器表达式更快,原因是其迭代在C中进行(有关原因,请阅读@Veedrac的评论)。但应该使用生成器表达式在元组中的唯一原因是您想对项目执行某些操作和/或过滤它们,更重要的是您想要一个元组(由于其不可变性及其针对可变对象的优点)。
毕竟,您始终可以使用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

6
“它的迭代在C中执行” → 这是关于Python最普遍、完全错误的神话之一。列表推导式更快是因为挂起和恢复函数帧很慢,而不是因为列表推导式特别特殊。 - Veedrac
@Veedrac,你有可靠的资源吗?因为据我所记,很久以前我从Mark Lutz的《学习Python》一书中读到过这个。如果不是这样(现在我认为你更有可能是对的),那么不仅这本书,还有其他著名的资源也需要严肃批评这种说法。 - Mazdak
我可以为您讲解编译此代码的过程(我甚至对其中的某些部分做出了贡献),但我目前在Google上找不到任何参考资料。我知道它们存在,因为我以前写过关于这个问题的文章,但我的Google搜索能力正在失败。 - Veedrac

2

生成器表达式(或简称为genexps)最好在循环中使用,以节省处理大量数据时的内存。不建议将genexp扩展为可迭代的数据类型(例如列表、元组、集合等)。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接