What's the most idiomatic way of writing a filter
with a negation?
Example:
is_even= lambda x : x % 2 == 0
odd_numbers= filter( lambda x: not is_even(x), range(10) )
Of course, you can just use list comprehensions - but then you needn't use filter
anyway
In case anyone wonders, I've stumbled upon this while trying to split a list based on a condition
The itertools
module includes both ifilter() and ifilterfalse(), which filter elements where the function returns True
and False
respectively.
odd_numbers = ifilterfalse(is_even, range(10))
Note that, in Python 2, there is a difference between filter
and ifilter
: odd_numbers
here would be an iterator, while filter() would give a list (see itertools.ifilter Vs. filter Vs. list comprehensions). If you actually want to build a list, your example with not
seems fine, assuming you are set on using filter
- list comprehensions may be more 'idiomatic' (List filtering: list comprehension vs. lambda + filter).
In Python 3, filter() constructs an iterator, not a list, and itertools.filterfalse() is the complement.
Splitting based on a predicate is called a partition
. I would find it more idiomatic to implement partition
as a separate function rather than repeat its internals specifically for odd and even numbers. Python 3's Itertools Recipes has the following implementation:
def partition(pred, iterable):
'Use a predicate to partition entries into false entries and true entries'
# partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9
t1, t2 = tee(iterable)
return filterfalse(pred, t1), filter(pred, t2)
It uses filterfalse
(as described by @Lack) and tee
defined in that module. So your highest-level code would look like:
odds, evens = partition(is_even, range(10))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With