【问题标题】:What is the advantage of a list comprehension over a for loop?列表推导比 for 循环有什么优势?
【发布时间】:2013-04-26 20:17:40
【问题描述】:

在 Python 中使用 list comprehensionfor 循环相比有什么优势?

主要是为了使其更具人类可读性,还是有其他原因使用列表推导而不是循环?

【问题讨论】:

  • 我认为在大多数(如果不是全部)情况下它们比 for 循环更快。也就是说,除了它们的美丽:)
  • “我们希望答案得到事实、参考资料或特定专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。”似乎可以用“特定事实[和]特定专业知识”来支持这个问题。将其标记为关闭的是 BS,IMO。
  • 转念一想,这不是一个“不具建设性”的问题,而且以前没有以这种形式提出过(与this相比),投票支持重新开放。
  • @MartijnPieters:所以这基本上取决于语义?像这样的事情真的让我很沮丧:很明显(至少对我来说)这个问题是以恰当的方式提出的。也许大卫和我同样不擅长阅读规则,但我有点怀疑......
  • @BenDundee:优势可能无穷无尽,因为优势在旁观者的眼中。

标签: python list-comprehension


【解决方案1】:

列表推导比构建列表的显式for 循环更紧凑

def slower():
    result = []
    for elem in some_iterable:
        result.append(elem)
    return result

def faster():
    return [elem for elem in some_iterable]

这是因为在 list 上调用 .append() 会导致列表对象增长(以块的形式)以单独为新元素腾出空间,而列表理解在创建 list 之前首先收集所有元素以适应元素一气呵成:

>>> some_iterable = range(1000)
>>> import timeit
>>> timeit.timeit('f()', 'from __main__ import slower as f', number=10000)
1.4456570148468018
>>> timeit.timeit('f()', 'from __main__ import faster as f', number=10000)
0.49323201179504395

但是,这并不意味着您应该开始对所有内容都使用列表推导式!列表推导仍然会构建一个列表对象;如果您只是因为它给您一个单行循环而使用列表推导,请再想一想。您可能正在浪费循环构建一个列表对象,然后再次丢弃。在这种情况下,只需坚持正常的 for 循环即可。

【讨论】:

  • 它们还使上面的代码更清晰。 (我认为您已经通过称它们为“显式”来涵盖这一点。)
  • 值得注意的是(尽管这个问题只要求优点)过度使用列表组合很容易导致代码更差,无论是效率还是可读性/可维护性。太多次我看到多个列表组合通过同一个循环,一个接一个。我还看到了用于中间结果的列表组合,这应该使用生成器组合来完成。您可以使用一系列以列表组合结尾的生成器组合来构建一个非常复杂的列表推导式,该列表推导式仍然有效。它们在孤立的情况下方便快捷,但要注意上下文!
  • @DylanYoung:绝对不应该对副作用使用列表推导。如果您使用列表推导式只是因为它会循环,那么您就是在浪费循环构建列表对象。
  • 绝对!不仅仅是副作用。通常,您想从同一个源列表(例如,用于反向引用)构建多个列表(或 dicts 等)。我经常看到这是作为一系列理解(列表和/或字典和/或集合)完成的,而单个循环可以完成所有这些。
  • @DylanYung:虽然单循环不会更有效。相同的算法复杂性适用,所以它会归结为常数因素。列表推导式在常数因素上获胜。
猜你喜欢
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2017-04-19
  • 2014-10-04
  • 2017-03-25
  • 1970-01-01
相关资源
最近更新 更多