Let's say I have a list, and a filtering function. Using something like
>>> filter(lambda x: x > 10, [1,4,12,7,42]) [12, 42]
I can get the elements matching the criterion. Is there a function I could use that would output two lists, one of elements matching, one of the remaining elements? I could call the filter()
function twice, but that's kinda ugly :)
Edit: the order of elements should be conserved, and I may have identical elements multiple times.
Python has a built-in function called filter() that allows you to filter a list (or a tuple) in a more beautiful way. The filter() function iterates over the elements of the list and applies the fn() function to each element. It returns an iterator for the elements where the fn() returns True .
To filter a list of tuples in Python: Use the filter() function to filter the list. The filter function returns an iterator containing the results. Pass the filter object to the list() class to convert it to a list.
filter() method is a very useful method of Python. One or more data values can be filtered from any string or list or dictionary in Python by using filter() method. It filters data based on any particular condition. It stores data when the condition returns true and discard data when returns false.
Try this:
def partition(pred, iterable): trues = [] falses = [] for item in iterable: if pred(item): trues.append(item) else: falses.append(item) return trues, falses
Usage:
>>> trues, falses = partition(lambda x: x > 10, [1,4,12,7,42]) >>> trues [12, 42] >>> falses [1, 4, 7]
There is also an implementation suggestion in itertools recipes:
from itertools import filterfalse, tee 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)
The recipe comes from the Python 3.x documentation. In Python 2.x filterfalse
is called ifilterfalse
.
>>> def partition(l, p): ... return reduce(lambda x, y: (x[0]+[y], x[1]) if p(y) else (x[0], x[1]+[y]), l, ([], [])) ... >>> partition([1, 2, 3, 4, 5], lambda x: x < 3) ([1, 2], [3, 4, 5])
and a little uglier but faster version of the above code:
def partition(l, p): return reduce(lambda x, y: x[0].append(y) or x if p(y) else x[1].append(y) or x, l, ([], []))
This is second edit, but I think it matters:
def partition(l, p): return reduce(lambda x, y: x[not p(y)].append(y) or x, l, ([], []))
The second and the third are as quick as the iterative one upper but are less code.
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