Permalink
Browse files

Added i?reductions()

  • Loading branch information...
1 parent ca824bc commit b906b11fdb702391506e77d0a295427f456b5e44 @Suor 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
View
@@ -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
-----
View
@@ -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
View
@@ -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):
View
@@ -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]

0 comments on commit b906b11

Please sign in to comment.