enhance partition

This commit is contained in:
gilch 2015-09-02 22:54:24 -06:00
parent 7a839aee5d
commit 4896980373
3 changed files with 50 additions and 13 deletions

View File

@ -671,21 +671,37 @@ Returns ``True`` if *x* is odd. Raises ``TypeError`` if
=> (odd? 0) => (odd? 0)
False False
.. _partition-fn: .. _partition-fn:
partition partition
--------- ---------
Usage: ``(partition n coll)`` Usage: ``(partition coll [n] [step] [fillvalue])``
Chunks coll into tuples of length *n*. The remainder, if any, is not included. Chunks *coll* into *n*-tuples (pairs by default).
.. code-block:: hy .. code-block:: hy
=> (list (partition 3 (range 10))) => (list (partition (range 10))) ; n=2
[(0, 1, 2), (3, 4, 5), (6, 7, 8)] [(, 0 1) (, 2 3) (, 4 5) (, 6 7) (, 8 9)]
The *step* defaults to *n*, but can be more to skip elements, or less for a sliding window with overlap.
.. code-block:: hy
=> (list (partition (range 10) 2 3))
[(, 0 1) (, 3 4) (, 6 7)]
=> (list (partition (range 5) 2 1))
[(, 0 1) (, 1 2) (, 2 3) (, 3 4)])
The remainder, if any, is not included unless a *fillvalue* is specified.
.. code-block:: hy
=> (list (partition (range 10) 3))
[(, 0 1 2) (, 3 4 5) (, 6 7 8)]
=> (list (partition (range 10) 3 :fillvalue "x"))
[(, 0 1 2) (, 3 4 5) (, 6 7 8) (, 9 "x" "x")]
.. _pos?-fn: .. _pos?-fn:

View File

@ -314,9 +314,17 @@
(_numeric-check n) (_numeric-check n)
(= (% n 2) 1)) (= (% n 2) 1))
(defn partition [n coll] (def -sentinel (object))
"Chunks coll into tuples of length n. The remainder, if any, is not included." (defn partition [coll &optional [n 2] step [fillvalue -sentinel]]
(apply zip (* n (, (iter coll))))) "Chunks coll into n-tuples (pairs by default). The remainder, if any, is not
included unless a fillvalue is specified. The step defaults to n, but can be
more to skip elements, or less for a sliding window with overlap."
(setv
step (or step n)
slices (genexpr (itertools.islice coll start nil step) [start (range n)]))
(if (is fillvalue -sentinel)
(apply zip slices)
(apply zip-longest slices {"fillvalue" fillvalue})))
(defn pos? [n] (defn pos? [n]
"Return true if n is > 0" "Return true if n is > 0"

View File

@ -473,14 +473,27 @@
(defn test-partition [] (defn test-partition []
"NATIVE: testing the partition function" "NATIVE: testing the partition function"
(setv ten (range 10)) (setv ten (range 10))
(assert-equal (list (partition 3 ten)) ;; no remainder
(assert-equal (list (partition ten 3))
[(, 0 1 2) (, 3 4 5) (, 6 7 8)]) [(, 0 1 2) (, 3 4 5) (, 6 7 8)])
(assert-equal (list (partition 2 ten)) ;; pair by default
(assert-equal (list (partition ten))
[(, 0 1) (, 2 3) (, 4 5) (, 6 7) (, 8 9)]) [(, 0 1) (, 2 3) (, 4 5) (, 6 7) (, 8 9)])
(assert-equal (list (partition 1 ten)) ;; length 1 is valid
(assert-equal (list (partition ten 1))
[(, 0) (, 1) (, 2) (, 3) (, 4) (, 5) (, 6) (, 7) (, 8) (, 9)]) [(, 0) (, 1) (, 2) (, 3) (, 4) (, 5) (, 6) (, 7) (, 8) (, 9)])
(assert-equal (list (partition 0 ten)) []) ;; tuples of length < 1 don't crash
(assert-equal (list (partition -1 ten)) [])) (assert-equal (list (partition ten 0)) [])
(assert-equal (list (partition ten -1)) [])
;; keep remainder with a fillvalue
(assert-equal (list (partition ten 3 :fillvalue "x"))
[(, 0 1 2) (, 3 4 5) (, 6 7 8) (, 9 "x" "x")])
;; skip elements with step > n
(assert-equal (list (partition ten 2 3))
[(, 0 1) (, 3 4) (, 6 7)])
;; overlap with step < n
(assert-equal (list (partition (range 5) 2 1))
[(, 0 1) (, 1 2) (, 2 3) (, 3 4)]))
(defn test-pos [] (defn test-pos []
"NATIVE: testing the pos? function" "NATIVE: testing the pos? function"