繁体   English   中英

Python-用于列表理解的动态过滤器?

[英]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 运算符开始。 containsnot应该足以给你想要的控制。 但是,这几乎比您当前的代码短,并且结果更难以阅读。 另一方面,这将使您对接下来要配置的内容有很多可爱的想法。

现在,我将采用这种方法。 它是有限的,但是它可以满足我当前的需求。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM