在Common Lisp中获取列表的前n个元素?

时间:2009-11-12 02:39:34

标签: list lisp common-lisp

我如何获得列表的第一个n元素?

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

我绝对肯定这是基本的,但帮助一个兄弟新手。

7 个答案:

答案 0 :(得分:28)

查看SUBSEQ功能。

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

它可能不是很明显,但是在Lisp中,索引从0开始,并且你总是采用半开间隔,因此这将使列表中的所有元素具有区间[0,2]中的索引。

答案 1 :(得分:5)

上面的回答当然是完全正确的,但请注意,如果您只是将其用于与另一个列表进行比较,那么将这两个列表就地放置,而不是列出新列表会更具性能效率只是为了比较。

例如,在上述情况下,您可能会说:

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

答案 2 :(得分:0)

递归:

(defun first-n (list n)
  "Returns the first n elements of the list."
  (when (not (zerop n))
    (cons (first list) (first-n (rest list) (1- n)))))

(first-n '(a b c d e) 3)        ;(A B C)

使用loop

(defun first-n-loop (list n)
  "Returns first n elements of the list."
  (loop for i below n
     collect (nth i list)))

(first-n-loop '(a b c d e) 3)       ;(A B C)

答案 3 :(得分:0)

修补核心CL功能:

(defun first-n (n list)
  "Returns the first N elements of the LIST."
  (butlast list (- (list-length list) n)))

(first-n 2 '(a s d f g))        ;(A S)

答案 4 :(得分:-1)

(defun pncar (n L)
  (setq L_ (list (nth 0 L)))
  (setq i 0)
  (if (and (< n 1) (< n (length L)))
    (setq L_ '())
    (repeat (- n 1) (progn
                      (setq i (+ i 1))
                      (if (/= nil (nth i L))
                        (setq L_ (append (list (nth i L)) L_))
                        (setq L_ '())
                        )
                      )
      )
    )
  (setq L_ (reverse L_))
  )

示例:

(pncar 0 '(0 1 2 3))
    nil
(pncar 1 '(0 1 2 3))
    (0)
(pncar 2 '(0 1 2 3))
    (0 1)
(pncar 3 '(0 1 2 3))
    (0 1 2)
(pncar 4 '(0 1 2 3))
    (0 1 2 3)
(pncar 5 '(0 1 2 3))
    nil

答案 5 :(得分:-2)

必须下载lisp命令行......但是:

(defun head-x (a b)
   (loop for x from 1 to a 
         for y = (car b) do 
            (setq b (cdr b)) 
         collect y))

这样:

(head-x 2 '(a b c d))
  '(a b)

答案 6 :(得分:-4)

(butlast'(1 20 300)( - (list-length'(1 20 300))2))

应该成为一个函数/宏。

P.S。 This page可能有用。参见'挤出'功能。