开发者

Multiple set comprehension in a functional style

开发者 https://www.devze.com 2023-02-04 09:46 出处:网络
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?

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消