def unique(iterable, is_sorted=False): """ Returns an iterable sequence of unique values from the given iterable. :param iterable: Iterable sequence. :param is_sorted: Whether the iterable has already been sorted. Works faster if it is. :returns: Iterable sequence of unique values. """ # If we used a "seen" set like the Python documentation implementation does, # we'd have to ensure that the elements are hashable. This implementation # does not have that problem. We can improve this implementation. if iterable: def _unique(memo, item): """Find uniques.""" cond = last(memo) != item if is_sorted else omits(memo, item) if cond: memo.append(item) return memo return _reduce(_unique, itail(iterable), [head(iterable)]) else: return iterable
def _flatten(memo, item): """Flattener.""" if isinstance(item, (list, tuple)): return memo + _reduce(_flatten, item, []) else: memo.append(item) return memo
def compose(function, *functions): """ Composes a sequence of functions such that:: compose(g, f, s) -> g(f(s())) :param functions: An iterable of functions. :returns: A composition function. """ def _composition(a, b): def wrap(*args, **kwargs): return a(b(*args, **kwargs)) return wrap return _reduce(_composition, functions, function)
def partition(predicate, iterable): """ Partitions an iterable into two iterables where for the elements of one iterable the predicate is true and for those of the other it is false. :param predicate: Function of the format:: f(x) -> bool :param iterable: Iterable sequence. :returns: Tuple (selected, rejected) """ def _partitioner(memo, item): part = memo[0] if predicate(item) else memo[1] part.append(item) return memo return tuple(_reduce(_partitioner, iterable, [[], []]))
def compose(function, *functions): """ Composes a sequence of functions such that:: compose(g, f, s) -> g(f(s())) :param functions: An iterable of functions. :returns: A composition function. """ def _composition(a_func, b_func): """Composition.""" def _wrap(*args, **kwargs): """Wrapper.""" return a_func(b_func(*args, **kwargs)) return _wrap return _reduce(_composition, functions, function)
def flatten(iterable): """ Flattens nested iterables into a single iterable. Example:: flatten((1, (0, 5, ('a', 'b')), (3, 4))) -> [1, 0, 5, 'a', 'b', 3, 4] :param iterable: Iterable sequence of iterables. :returns: Iterable sequence of items. """ def _flatten(memo, item): if isinstance(item, (list, tuple)): return memo + _reduce(_flatten, item, []) else: memo.append(item) return memo return _reduce(_flatten, iterable, [])
def reduce(transform, iterable, *args): """ Aggregate a sequence of items into a single item. Python equivalent of Haskell's left fold. Please see Python documentation for reduce. There is no change in behavior. This is simply a wrapper function. If you need reduce_right (right fold):: reduce_right = foldr = lambda f, i: lambda s: reduce(f, s, i) :param transform: Function with signature:: f(x, y) :param iterable: Iterable sequence. :param args: Initial value. :returns: Aggregated item. """ return _reduce(transform, iterable, *args)