Is there a filter() opposite builtin?

余生长醉 提交于 2019-12-19 05:14:33

问题


Is there a function in Python that does the opposite of filter? I.e. keeps the items in the iterable that the callback returns False for? Couldn't find anything.


回答1:


No, there is no built-in inverse function for filter(), because you could simply invert the test. Just add not:

positive = filter(lambda v: some_test(v), values)
negative = filter(lambda v: not some_test(v), values)

The itertools module does have itertools.ifilterfalse(), which is rather redundant because inverting a boolean test is so simple. The itertools version always operates as a generator.




回答2:


You can do this with itertools.filterfalse or as Martijn suggests, put a not somewhere inside the lambda you use in your filter.




回答3:


Another option:

from operator import not_
compose = lambda f, g: lambda x: f( g(x) )

...

ys = filter(compose(not_, predicate), values)

You may have a pre-rolled version of compose() available (e.g. in functional or toolz).




回答4:


From Ross Bencina's comment to Martijn Pieters's answer:

Your reasoning is not very convincing. The first case can already be written

positive = filter(some_test, values)

therefore what is asked for should be at least as simple as

negative = filter(not(some_test), values)

I would suggest using a simple negating wrapper function:

def _not(func):
    def not_func(*args, **kwargs):
        return not func(*args, **kwargs)
    return not_func

which allows to write the second line as above (with the added underscore or other distinction, since the not operator cannot and probably should not be overwritten):

negative = filter(_not(some_test), values)



回答5:


I had the same situation, but I didn't wanted to have duplicated functions for my filter. This is my solution to filter the items of a dictionary and be able to invert the selection.

req_table = {
    "ID_4001" : {"R_STAT":True, "V_STAT":False, "TYPE":"X", "VEL": 1},
    "ID_0051" : {"R_STAT":True, "V_STAT":True,  "TYPE":"X", "VEL": 23},
    "ID_0741" : {"R_STAT":True, "V_STAT":False, "TYPE":"Y", "VEL": 32},
    "ID_0701" : {"R_STAT":True, "V_STAT":False, "TYPE":"X", "VEL": 2353},
}

def count_prop(prop, with_val, rq_table, invert=False):
    return len(list(filter(lambda tc : (tc[1][prop] == with_val)^invert, rq_table.items())))

print("Items of type X: {}".format(count_prop("TYPE", "X", req_table)))
print("Items of type Y: {}".format(count_prop("TYPE", "X", req_table, invert=True)))

The trick is the ^ which acts as a enabled not.



来源:https://stackoverflow.com/questions/33989155/is-there-a-filter-opposite-builtin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!