列表推导式 vs lambda + filter

25 浏览
0 Comments

列表推导式 vs lambda + filter

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

哪种方式更受欢迎(易读性、性能、其他原因)?

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

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

admin 更改状态以发布 2023年5月24日
0
0 Comments

这是Python中一个略带宗教色彩的问题。虽然Guido曾考虑将mapfilterreduce从Python 3中移除,但是由于引起了足够激烈的反弹,最后只有reduce从内置函数被移动到functools.reduce中。

个人认为列表解析更容易阅读。通过表达式[i for i in list if i.attribute == value]可以更清楚地表达出所有的行为,而不是在过滤函数内部进行实现。

我不会过分担心这两种方法之间的性能差异,因为它是微不足道的。我真正只会在应用程序中这部分代码成为瓶颈的情况下去优化它,而这是不太可能发生的。

另外,由于BDFL在语言中希望去掉filter,因此肯定会使列表解析更符合Python的特性;-)

0
0 Comments

很奇怪人们对于美的认知存在很大差别。我认为列表推导式比filter+lambda更明确,但你可以使用你觉得更容易的方法。

有两件事情可能会降低你使用filter的速度。

第一件事是函数调用的开销:一旦你使用Python函数(不管是通过def还是lambda创建的),filter很可能会比列表推导式慢。这几乎肯定是微不足道的,你不应该太关注性能,直到你计时后发现这是一个问题,但差别确实存在。

另一个可能适用的开销是lambda被强制访问一个作用域变量(value)。这比访问局部变量慢,在Python 2.x中,列表推导式只访问局部变量。如果你使用的是Python 3.x,列表推导式在一个独立的函数中运行,因此也将通过闭包访问value,这个差别将不适用。

另一个要考虑的选择是使用生成器而不是列表推导式:

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

然后在你的主要代码中(这是真正重要的可读性),你用一个有意义的函数名替换了列表推导式和filter

0