[英]Python - dynamic filter for list comprehension?
我想编写一种方法,该方法将根据提供的操作符或函数来过滤给定的对象列表。
现在我的方法如下:
def filter_by_names(objects, names, exclude=False):
if exclude:
return [obj for obj in objects if obj.name not in names]
else:
return [obj for obj in objects if obj.name in names]
现在,它具有两个过滤器选项,如果名称在提供的名称列表中,则返回对象或执行相反的操作:返回名称不在提供的名称列表中的对象。
我想要的是能够动态指定如何过滤。 我虽然使用operator
库,但似乎not in
运算符,因此我需要将not
合并在一起in
这有点笨拙。
我当时在考虑使用lambda,例如:
def filter_by_names(objects, names, fun=lambda obj, names: obj.name in names):
return [obj for obj in objects if fun(obj, names)]
这是可行的,但我想知道也许有更好的方法来做类似的事情? 使用lambda时,即使我只需要其他运算符,也总是需要指定整个函数。
例如,如何使用xor运算符
>>> n = range(0,11,2)
>>> n
[0, 2, 4, 6, 8, 10]
>>> exclude = True
>>> [ x for x in range(10) if (x in n) ^ exclude ] # only the one that are not in n
[1, 3, 5, 7, 9]
>>> exclude = False
>>> [ x for x in range(10) if (x in n) ^ exclude ] # only the one that are also in n
[0, 2, 4, 6, 8]
>>>
这项工作的原因是,等于的异或结果为false,不同的异或结果为true
def filter_by_names(objects, names, exclude=False):
return [obj for obj in objects if (obj.name in names) == (not exclude)]
用not exclude
(而不是(obj.name not in names) == exclude)
)来编写该(obj.name not in names) == exclude)
可以使您为“ exclude”传递任意的true / falsy值,而不仅仅是True或False。
从Python 运算符开始。 contains
和not
应该足以给你想要的控制。 但是,这几乎比您当前的代码短,并且结果更难以阅读。 另一方面,这将使您对接下来要配置的内容有很多可爱的想法。
现在,我将采用这种方法。 它是有限的,但是它可以满足我当前的需求。
def filter_by_names(objects, names, exclude=False):
def _filter(names, name):
if exclude:
return name not in names
return name in names
return [obj for obj in objects if _filter(names, obj.name)]
PS我删除了operator
库,因为使用两种方式都受限制的函数,因此不需要operator
lib。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.