我碰巧发现自己有一个基本的过滤需求:我有一个列表,我必须根据项目的属性进行过滤.

我的代码如下所示:

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

但后来我想,这样写不是更好吗?

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

它更具可读性,如果性能需要,可以取出lambda来获得一些东西.

问题是:在使用第二种方法时有什么注意事项吗?性能有什么不同吗?我错过了Python 的方式吗™ 而且应该以另一种方式(比如使用itemgetter而不是lambda)来完成吗?

推荐答案

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

有两件事可能会减缓你使用filter的速度.

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

另一个可能适用的开销是强制lambda访问限定了作用域的变量(value).这比访问局部变量慢,而且在Python2.x中,列表理解只访问局部变量.如果您使用的是Python3.x,那么列表理解在一个单独的函数中运行,因此它也将通过闭包访问value,这种差异将不适用.

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

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

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

Python相关问答推荐

Pydantic 2.7.0模型接受字符串日期时间或无

Deliveryter Notebook -无法在for循环中更新matplotlib情节(保留之前的情节),也无法使用动画子功能对情节进行动画

查找两极rame中组之间的所有差异

无法通过python-jira访问jira工作日志(log)中的 comments

使用Python更新字典中的值

如何在UserSerializer中添加显式字段?

如何使用scipy的curve_fit与约束,其中拟合的曲线总是在观测值之下?

如何更新pandas DataFrame上列标题的de值?

Python中的变量每次增加超过1

Polars asof在下一个可用日期加入

如何按row_id/row_number过滤数据帧

将一个双框爆炸到另一个双框的范围内

pandas fill和bfill基于另一列中的条件

删除特定列后的所有列

仅使用预先计算的排序获取排序元素

如何训练每一个pandaprame行的线性回归并生成斜率

为罕见情况下的回退None值键入

如何在Python中自动创建数字文件夹和正在进行的文件夹?

普洛特利express 发布的人口普查数据失败

有什么方法可以在不对多索引DataFrame的列进行排序的情况下避免词法排序警告吗?