Suor/funcy

1 parent ca824bc commit b906b11fdb702391506e77d0a295427f456b5e44 committed Feb 28, 2013
Showing with 30 additions and 1 deletion.
1. +4 −0 docs/seqs.rst
2. +0 −1 from_clojure.txt
3. +18 −0 funcy/seqs.py
4. +8 −0 tests/test_seqs.py
 @@ -160,6 +160,10 @@ This section provides some robust tools for sequence slicing. Consider :ref:`sli ilen(takewhile(lambda (x,y): x == y, zip(s1, s2))) +.. function:: reductions(f, seq, [acc]) + ireductions(f, seq, [acc]) + + Unite -----
 @@ -18,4 +18,3 @@ Get shorter: idistinct,p Slicing: last,p butlast,p take_last,p drop_last,p Change: flatten,p partition_by,p replace? Process: pmap,p map_indexed? -Construct coll: reductions,p
 @@ -6,6 +6,7 @@ __all__ = ['count', 'cycle', 'repeat', 'repeatedly', 'iterate', 'take', 'drop', 'first', 'second', 'rest', 'ilen', + 'ireductions', 'reductions', 'imap', 'ifilter', 'remove', 'iremove', 'keep', 'ikeep', 'concat', 'iconcat', 'cat', 'icat', 'mapcat', 'imapcat', 'izip', 'interleave', 'interpose', 'distinct', @@ -44,6 +45,23 @@ def ilen(seq): return sum(1 for _ in seq) +EMPTY = object() + +def ireductions(f, seq, acc=EMPTY): + it = iter(seq) + if acc is EMPTY: + last = next(it) + yield last + else: + last = acc + for x in it: + last = f(last, x) + yield last + +def reductions(f, seq, acc=EMPTY): + return list(ireductions(f, seq, acc)) + + # TODO: tree-seq equivalent def remove(pred, seq):
 @@ -1,4 +1,5 @@ from collections import Iterator +from operator import add import pytest from whatever import _ @@ -30,6 +31,13 @@ def test_first(): assert first([]) is None +def test_reductions(): + assert reductions(add, []) == [] + assert reductions(add, [None]) == [None] + assert reductions(add, [1, 2, 3, 4]) == [1, 3, 6, 10] + assert reductions(lambda x, y: x + [y], [1,2,3], []) == [[1], [1, 2], [1, 2, 3]] + + def test_remove(): assert remove(_ > 3, range(10)) == [0, 1, 2, 3]