At one point I recall reading in a Lisp book about a function which
would
take a list as input and break it up into a list of n-element sublists
plus
the remainder, e.g.
(foo 3 '(1 2 3 4 5 6 7)) => ((1 2 3) (4 5 6) (7))
The trouble is I can't remember its name, or whether it was standard or
a
user-defined function. I looked through the HyperSpec and c.l.l for
all the
synonyms of "group", "partition", etc I could think of, but found
nothing.
Does anyone know what I'm thinking of?
In article <························@g47g2000cwa.googlegroups.com>,
······@gmail.com wrote:
> At one point I recall reading in a Lisp book about a function which
> would
> take a list as input and break it up into a list of n-element sublists
> plus
> the remainder, e.g.
>
> (foo 3 '(1 2 3 4 5 6 7)) => ((1 2 3) (4 5 6) (7))
>
> The trouble is I can't remember its name, or whether it was standard or
> a
> user-defined function. I looked through the HyperSpec and c.l.l for
> all the
> synonyms of "group", "partition", etc I could think of, but found
> nothing.
> Does anyone know what I'm thinking of?
It's not a standard Common Lisp function, and I can't think of any other
well-known Lisp dialects that are likely to have this built-in. It
doesn't seem like a common idiom that needs to be predefined in the
language, it seems more like the kind of thing that would be assigned as
a homework problem in a beginning class.
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Barry Margolin teithant i thiw hin:
> It's not a standard Common Lisp function, and I can't think of any
> other well-known Lisp dialects that are likely to have this
> built-in. It doesn't seem like a common idiom that needs to be
> predefined in the language, it seems more like the kind of thing
> that would be assigned as a homework problem in a beginning class.
Well, I'm mainly interested in the case where n = 2; I'm turning a
user-supplied list of symbols into a bunch of key-value pairs to use
for a macro. I just read something similar the other day and couldn't
remember the context in which it was described.
--
J "bad line wrapping courtesy of Google" W
······@gmail.com wrote:
> Barry Margolin teithant i thiw hin:
> > It's not a standard Common Lisp function, and I can't think of any
> > other well-known Lisp dialects that are likely to have this
> > built-in. It doesn't seem like a common idiom that needs to be
> > predefined in the language, it seems more like the kind of thing
> > that would be assigned as a homework problem in a beginning class.
>
> Well, I'm mainly interested in the case where n = 2; I'm turning a
> user-supplied list of symbols into a bunch of key-value pairs to use
> for a macro. I just read something similar the other day and couldn't
> remember the context in which it was described.
If I understand correctly, I think that's often done by the following
idiom:
(loop for (i j) on ... by #'cddr
...)
Tayssir
; (break-n 3 '(1 2 3 4 5 6 7)) => ((1 2 3) (4 5 6) (7))
; break up a list into n parts
(defun break-n(n lst)
(break-n-lst n lst (length lst)))
; break up a list of length len into parts of length n and a remainder
(defun break-n-lst(n lst len)
(cond
((>= n len)
(list lst))
((< n len)
(cons
(loop for x from 0 to (- n 1) collect (nth x lst))
(break-n-lst n (nthcdr n lst) (- len n))))))
······@gmail.com writes:
> At one point I recall reading in a Lisp book about a function which
> would
> take a list as input and break it up into a list of n-element sublists
> plus
> the remainder, e.g.
>
> (foo 3 '(1 2 3 4 5 6 7)) => ((1 2 3) (4 5 6) (7))
>
> The trouble is I can't remember its name, or whether it was standard or
> a
> user-defined function. I looked through the HyperSpec and c.l.l for
> all the
> synonyms of "group", "partition", etc I could think of, but found
> nothing.
> Does anyone know what I'm thinking of?
split ?
(defun split (n list)
(labels ((at-most (l n c)
(if (or (null l) (zerop c)) (- n c) (at-most (cdr l) n (1- c)))))
(loop :for s :on list :by (lambda (l) (nthcdr n l))
:collect (subseq s 0 (at-most s n n)))))
--
__Pascal Bourguignon__ http://www.informatimago.com/
······@gmail.com writes:
> At one point I recall reading in a Lisp book about a function which
> would
> take a list as input and break it up into a list of n-element sublists
> plus
> the remainder, e.g.
>
> (foo 3 '(1 2 3 4 5 6 7)) => ((1 2 3) (4 5 6) (7))
>
> The trouble is I can't remember its name, or whether it was standard or
> a
> user-defined function. I looked through the HyperSpec and c.l.l for
> all the
> synonyms of "group", "partition", etc I could think of, but found
> nothing.
> Does anyone know what I'm thinking of?
Stealing nthcdr from Justin and subseq from Pascal, I get
* (defun group (n list)
(if (not (endp (nthcdr n list)))
(cons (subseq list 0 n)
(group n (nthcdr n list)))
(list list)))
(group 3 '(1 2 3 4 5 6 7)) => ((1 2 3) (4 5 6) (7))
Alan Crowe
Edinburgh
Scotland
On 14 Oct 2005 10:46:55 +0100, <····@cawtech.freeserve.co.uk> wrote:
>
>
> ······@gmail.com writes:
>> At one point I recall reading in a Lisp book about a function which
>> would
>> take a list as input and break it up into a list of n-element sublists
>> plus
>> the remainder, e.g.
>>
>> (foo 3 '(1 2 3 4 5 6 7)) => ((1 2 3) (4 5 6) (7))
>>
>> The trouble is I can't remember its name, or whether it was standard or
>> a
>> user-defined function. I looked through the HyperSpec and c.l.l for
>> all the
>> synonyms of "group", "partition", etc I could think of, but found
>> nothing.
>> Does anyone know what I'm thinking of?
>
> Stealing nthcdr from Justin and subseq from Pascal, I get
>
> * (defun group (n list)
> (if (not (endp (nthcdr n list)))
> (cons (subseq list 0 n)
> (group n (nthcdr n list)))
> (list list)))
>
> (group 3 '(1 2 3 4 5 6 7)) => ((1 2 3) (4 5 6) (7))
>
> Alan Crowe
> Edinburgh
> Scotland
--
If you don't like LOOP, how do you feel about DOLIST ?
GP lisper <········@CloudDancer.com> writes:
> On 14 Oct 2005 10:46:55 +0100, <····@cawtech.freeserve.co.uk> wrote:
> > * (defun group (n list)
> > (if (not (endp (nthcdr n list)))
> > (cons (subseq list 0 n)
> > (group n (nthcdr n list)))
> > (list list)))
>
> If you don't like LOOP, how do you feel about DOLIST ?
I'm not that hot a Lisp programmer. An early draft for this
code had
(defun first-few (n list)
(loop repeat n
for x in list
collect x))
instead of just using (subseq list 0 n). Embarrassing.
If you have slick LOOP code, share!
Alan Crowe
Edinburgh
Scotland
Alan Crowe wrote:
> GP lisper <········@CloudDancer.com> writes:
> > On 14 Oct 2005 10:46:55 +0100, <····@cawtech.freeserve.co.uk> wrote:
> > > * (defun group (n list)
> > > (if (not (endp (nthcdr n list)))
> > > (cons (subseq list 0 n)
> > > (group n (nthcdr n list)))
> > > (list list)))
> >
> > If you don't like LOOP, how do you feel about DOLIST ?
>
> I'm not that hot a Lisp programmer. An early draft for this
> code had
>
> (defun first-few (n list)
> (loop repeat n
> for x in list
> collect x))
>
> instead of just using (subseq list 0 n). Embarrassing.
>
> If you have slick LOOP code, share!
>
> Alan Crowe
> Edinburgh
> Scotland
subseq! that's just what I need to get my card game dealing code down
in size. sweet
Alan Crowe wrote:
> GP lisper <········@CloudDancer.com> writes:
>
>>On 14 Oct 2005 10:46:55 +0100, <····@cawtech.freeserve.co.uk> wrote:
>>
>>>* (defun group (n list)
>>> (if (not (endp (nthcdr n list)))
>>> (cons (subseq list 0 n)
>>> (group n (nthcdr n list)))
>>> (list list)))
>>
>>If you don't like LOOP, how do you feel about DOLIST ?
>
>
> I'm not that hot a Lisp programmer. An early draft for this
> code had
>
> (defun first-few (n list)
> (loop repeat n
> for x in list
> collect x))
>
> instead of just using (subseq list 0 n). Embarrassing.
Actually, in this case it may not be a bad idea, because by using LOOP
you can avoid the explicit check for the out of bounds error. Take the
following LOOPs:
(defun split-list (n list)
(loop for cons on list
by #'(lambda (x) (nthcdr n x))
if (< 0 n)
collect (loop for atom in cons
repeat n
collect atom)
else return nil))
CL-USER> (split-list 0 (list 1 2 3 4 5 6 7 8))
NIL
CL-USER> (split-list 1 (list 1 2 3 4 5 6 7 8))
((1) (2) (3) (4) (5) (6) (7) (8))
CL-USER> (split-list 3 (list 1 2 3 4 5 6 7 8))
((1 2 3) (4 5 6) (7 8))
CL-USER> (split-list 40000 (list 1 2 3 4 5 6 7 8))
((1 2 3 4 5 6 7 8))
CL-USER> (split-list 40000 (list 1 2 3 4 5 6 7 8))
((1 2 3 4 5 6 7 8))
> If you have slick LOOP code, share!
I use loop for this sort of thing all the time. I find it reads as a
clear solution to the problem without cluttering my code with bounds
checks, and i don't have to think as hard about it versus a recursive
solution. Plus, i just get a kick out of loop... it's a lot of fun :)
--
Drew Crampsie
drewc at tech dot coop
"... the most advanced use of lisp in the field of bass lure sales"
-- Xach on #lisp
······@gmail.com writes:
> At one point I recall reading in a Lisp book about a function which
> would
> take a list as input and break it up into a list of n-element sublists
> plus
> the remainder, e.g.
>
> (foo 3 '(1 2 3 4 5 6 7)) => ((1 2 3) (4 5 6) (7))
>
> The trouble is I can't remember its name, or whether it was standard or
Graham has some functions like that in On Lisp. Called group
and group-by.
And unlike Barry, I've actually found use for those in production code...
--ap