列表理解与 lambda 过滤器

新手上路,请多包涵

我有一个列表,我想按项目的属性进行过滤。

以下哪项是首选(可读性、性能、其他原因)?

 xs = [x for x in xs if x.attribute == value]

 xs = filter(lambda x: x.attribute == value, xs)

原文由 Agos 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 339
2 个回答

奇怪的是,不同的人的美有多少不同。我发现列表理解比 filter + lambda 更清晰,但使用你觉得更容易的那个。

有两件事可能会减慢您对 filter 的使用。

第一个是函数调用开销:一旦您使用 Python 函数(无论是由 def 还是 lambda 创建),过滤器很可能会比列表理解慢。几乎可以肯定这还不够重要,在您对代码计时并发现它是瓶颈之前,您不应该过多考虑性能,但区别就在那里。

可能适用的其他开销是 lambda 被强制访问范围变量 ( value )。这比访问局部变量要慢,而且在 Python 2.x 中,列表推导式只访问局部变量。如果您使用的是 Python 3.x,则列表推导式在单独的函数中运行,因此它也将通过闭包访问 value ,并且这种差异将不适用。

另一个要考虑的选项是使用生成器而不是列表理解:

 def filterbyvalue(seq, value):
   for el in seq:
       if el.attribute==value: yield el

然后在您的主代码中(这是可读性真正重要的地方),您已经用一个有希望有意义的函数名称替换了列表理解和过滤器。

原文由 Duncan 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是 Python 中的一个有点宗教性的问题。 Even though Guido considered removing map , filter and reduce from Python 3 , there was enough of a backlash that in the end only reduce 已从内置函数移至 functools.reduce

我个人觉得列表理解更容易阅读。表达式 [i for i in list if i.attribute == value] 中发生的事情更加明确,因为所有行为都在表面上而不是在过滤器函数内部。

我不会太担心这两种方法之间的性能差异,因为它是微不足道的。如果它被证明是您的应用程序中的瓶颈(这不太可能),我真的只会优化它。

此外,由于 BDFL 想要 filter 从语言中消失,那么肯定会自动使列表理解更像 Pythonic ;-)

原文由 Tendayi Mawushe 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题