我想编写一个方法来过滤给定的对象列表,具体取决于提供哪些运算符或函数来过滤。
现在我的方法看起来像这样:
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
运算符,所以我需要将in
与not
结合起来,这有点笨拙。
我在考虑使用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我总是需要指定整个函数,即使我只需要不同的运算符。
答案 0 :(得分:2)
如何使用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]
>>>
这项工作是因为等于的xor导致为false,而不同的xor导致为真
答案 1 :(得分:1)
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)
)来写这个内容,可以为'排除'传递任意的真值/假值,而不仅仅是真或假。
答案 2 :(得分:0)
从Python operators开始。 contains
和not
应足以为您提供所需的控制权。但是,这将比您当前的代码短得多,结果更难以阅读。另一方面,这应该会为您提供关于下一步要配置的许多可爱的想法。
答案 3 :(得分:0)
现在我采用这种方法。它有点受限,但它确实是我目前所需要的。
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)]
P.S。我删除了operator
库,因为使用受限于任何方式的函数,不需要operator
库。