Multiple set comprehension in a functional style
Does any one know of a function/idiom (in any language) that takes a set and returns two or more subsets, determined by one or more predicates?
It is easy to do this in an imperative style e.g:
a = b = []
for x in range(10):
if even(x):
a.append(x)
else:
b.append(x)
or slightly better:
[even(x) and a.append(x) or b.append(x) for x in range(10)]
Since a set comprehension returns a single list based upon a single predicate (and it effectively just a map) I think there ought to be something that splits the input into 2 or more bins based on either a binary predicate or multiple predicates.
The neatest syntax I can come up with is:
>> def partition(iterable, *functions):
>> return [filter(f,iterable) for f in functions]
>> partition(range(10), la开发者_如何转开发mbda x: bool(x%2), lambda x: x == 2)
[[1, 3, 5, 7, 9], [2]]
Searching for (a -> Bool) -> [a] -> ([a], [a])
on Hoogle yields Data.List.partition
.
The
partition
function takes a predicate a list and returns the pair of lists of elements which do and do not satisfy the predicate, respectively; i.e.,partition p xs == (filter p xs, filter (not . p) xs)
If you look at its source and translate to Python,
def partition(predicate, sequence):
def select((yes, no), value):
if predicate(value):
return (yes + [value], no)
else:
return (yes, no + [value])
return reduce(select, sequence, ([], []))
which is pretty nicely functional. Unlike the original, it's not lazy, but that's a bit trickier to pull off in Python.
Ruby's Enumerable
mixin has a partition
method that does what you describe.
精彩评论