Getting the first n elements of a list in Common Lisp?

14,570

Solution 1

Check out the SUBSEQ function.

* (equal (subseq '(1 20 300) 0 2)
         '(1 20))
T

It may not be immediately obvious, but in Lisp, indexing starts from 0, and you're always taking half-open intervals, so this takes all the elements of the list with indices in the interval [0, 2).

Solution 2

The above answer is of course perfectly correct, but note that if you're using this just to compare against another list, it would be more performance-efficient to walk both lists in-place, rather than consing up a new list just to compare.

For example, in the above case, you might say:

(every #'= '(1 20 300) '(1 20))
=> t

Love,

Share:
14,570
Admin
Author by

Admin

Updated on June 03, 2022

Comments

  • Admin
    Admin almost 2 years

    How would I get the first n elements of a list?

    CL-USER> (equal (some-function 2 '(1 20 300))
                    '(1 20))
    T
    

    I am absolutely certain this is elementary, but help a brother newb out.

  • Pillsy
    Pillsy over 14 years
    Just use (loop :repeat a :for x :in b :collect x) as your function body. Much simpler.
  • beggs
    beggs over 14 years
    Thanks... been years since I actually did any lisp. Thought it be fun to answer a question!
  • Rainer Joswig
    Rainer Joswig over 14 years
    Definitely not a good idea to compute the length of a list for getting some elements from the front. Unlispy!
  • Diego Sevilla
    Diego Sevilla over 12 years
    This has the unfortunate restriction that it will fail in runtime if the sequence is smaller than the ending index, which is a pity, because asking for the length before is highly inefficient. So how to proceed in this case?
  • Diego Sevilla
    Diego Sevilla over 12 years
    Well, looking at Practical Common Lisp: gigamonkeys.com/book/loop-for-black-belts.html comes the right answer: (loop for item in list for i from 1 to 10 do (something)) where that something could be collecting item.
  • Pillsy
    Pillsy over 12 years
    @DiegoSevilla Sometimes having the code fail at runtime when you don't have enough elements in your list is exactly the behavior you're looking for. A lot of idiomatic Common Lisp code builds fixed-size data structures out of conses instead of using DEFCLASS or DEFSTRUCT, and in those instances, if you don't have enough elements, getting tossed into the debugger immediately is the best thing that can happen to you.
  • Svante
    Svante over 4 years
    This has some unneeded overhead because it has to walk the entire list to determine the list length first. It will even fail if the list is circular.