问题
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