在Python的filter中链接操作符函数

2 投票
2 回答
937 浏览
提问于 2025-04-16 05:00

我有一堆对象的列表,想根据一些条件来筛选它们。我可以用列表推导式来做到这一点:

import datetime, pytz
# let's have a range of 100 hourly datetimes (just an example!):
dates = [ datetime.datetime(2010, 10, 1, 0, 0, 0, 0, pytz.utc) + datetime.timedelta(hours=i) for i in xrange(100) ]

# now I want a list of all dates, where hour in (0, 6, 12, 18)...
[ dt for dt in dates if dt.hour % 6 == 0 ]

这样做是正确的。

那么我该如何使用 filter 函数呢?因为我的数据集会很大,所以速度很重要。我可以检查一下 dt.hour 是否为真(也就是不等于 0):

import operator

filter(operator.attrrgetter('hour'), dates)

但是我该如何把 (6).__rmod__ 这一部分加进去呢?这部分可以告诉我 hour 属性是否能被 6 整除?

2 个回答

1

很遗憾,没有现成的方法可以直接做rmod,所以最好的办法是使用一个lambda表达式(或者一个列表推导式)。

filter(lambda x: not x.hour % 6, dates)
4

一种方法是使用自定义的 lambda 函数。这个写法比较详细,以便于理解。

filter(lambda dt: hasattr(dt, 'hour') and dt.hour % 6, dates)

如果你在 dates 这个序列中可能会遇到非日期对象,那么就需要进行 hasattr 检查。

我想补充一下,列表推导式比 mapfilter 更受欢迎。你可以把上面的代码改写成:

[dt for dt in dates if hasattr(dt, 'hour') and dt.hour % 6]

撰写回答