我有一个列表,我想按项目的属性进行过滤。
以下哪项是首选(可读性、性能、其他原因)?
xs = [x for x in xs if x.attribute == value]
xs = filter(lambda x: x.attribute == value, xs)
原文由 Agos 发布,翻译遵循 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 许可协议
2 回答5.2k 阅读✓ 已解决
2 回答1.1k 阅读✓ 已解决
4 回答1.4k 阅读✓ 已解决
3 回答1.3k 阅读✓ 已解决
3 回答1.2k 阅读✓ 已解决
2 回答850 阅读✓ 已解决
1 回答1.7k 阅读✓ 已解决
奇怪的是,不同的人的美有多少不同。我发现列表理解比
filter
+lambda
更清晰,但使用你觉得更容易的那个。有两件事可能会减慢您对
filter
的使用。第一个是函数调用开销:一旦您使用 Python 函数(无论是由
def
还是lambda
创建),过滤器很可能会比列表理解慢。几乎可以肯定这还不够重要,在您对代码计时并发现它是瓶颈之前,您不应该过多考虑性能,但区别就在那里。可能适用的其他开销是 lambda 被强制访问范围变量 (
value
)。这比访问局部变量要慢,而且在 Python 2.x 中,列表推导式只访问局部变量。如果您使用的是 Python 3.x,则列表推导式在单独的函数中运行,因此它也将通过闭包访问value
,并且这种差异将不适用。另一个要考虑的选项是使用生成器而不是列表理解:
然后在您的主代码中(这是可读性真正重要的地方),您已经用一个有希望有意义的函数名称替换了列表理解和过滤器。