def filter_both(predicate, iterable):
    """
    Splits the iterable into two groups, based on the result of
    calling `predicate` on each element.

    WARN: Consumes the whole iterable in the process. This is the
    price for calling the `predicate` function only once for each
    element. (See itertools recipes for similar functionality without
    this requirement.)

    >>> filter_both(lambda x: x%2 == 0, range(4))
    ([0, 2], [1, 3])
    """
    yes, no = [], []
    for i in iterable:
        if predicate(i):
            yes.append(i)
        else:
            no.append(i)
    return yes, no