【问题标题】:Python 3.x list comprehension VS tuple generatorPython 3.x 列表理解 VS 元组生成器
【发布时间】:2017-10-04 03:02:06
【问题描述】:

我想使用内存、速度或其他什么原因:

tuple(i for i in range(5000))

代替:

[i for i in range(5000)]

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

【问题讨论】:

  • 如果你需要一个元组,使用前者,如果你需要一个列表,使用后者(或list(range(5000)))。
  • tuplelist 之间的选择取决于您计划使用它而不是资源。
  • 除了转换的开销之外,元组会更小更快,因为它缺乏使其可变的机制,允许快速插入等。但是转换当然需要额外的时间(一次) .
  • 第一个会慢一些,虽然它可能会占用更少的内存(最终)
  • 为了速度,您可以删除不需要的理解 ;) tuple(range(5000))list(range(5000)),或者,根据您的需要,只需 range(5000)

标签: python python-3.x list performance generator


【解决方案1】:

基本上,列表推导比生成器表达式更快,原因是 它的迭代在 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

【讨论】:

  • “它的迭代在 C 中执行” → 这是关于 Python 的最普遍、完全错误的神话之一。列表推导更快是因为暂停和恢复函数的帧很慢,而不是因为列表推导有什么特别之处。
  • @Veedrac 你有任何可靠的资源吗?因为,据我所知,很久以前我从 Mark Lutz Learning python 的书中读到过。如果不是这样(现在我认为你更可能是对的)不仅那本书,而且其他可能提到此声明的著名资源都需要认真批评。
  • 我可以引导您完成编译它的代码(我什至贡献了其中的一部分),但目前我在 Google 上找不到任何参考资料。我知道它们的存在是因为我以前写过这方面的文章,但是我的 Google-fu 让我失望了。
【解决方案2】:

生成器表达式(或简称​​genexps)最适合在循环中使用,以在处理大量数据时节省内存。将 genexp 扩展为可交互的数据类型(例如列表、元组、集合)并不是一种好的做法。

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

【讨论】:

    猜你喜欢
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    • 2013-12-30
    相关资源
    最近更新 更多