将项目添加到列表末尾的“缺点”是什么?

时间:2011-06-22 12:39:03

标签: list append lisp common-lisp

将项目添加到列表末尾的典型方法是什么?

我有一个列表(1 2 3)并且想要添加4(其中4是评估结果(+ 2 2))

(setf nlist '(1 2 3))  
(append nlist (+ 2 2))  

这表示append需要一个列表,而不是一个数字。我该如何做到这一点?

9 个答案:

答案 0 :(得分:27)

您可以使用append,但请注意,如果在循环或非常长的列表中使用它会导致性能下降。

(append '(1 2 3) (list (+ 2 2)))

如果表现很重要,通常的习惯是通过预先(使用cons),然后reverse(或nreverse)来构建列表。

答案 1 :(得分:6)

如果“前面的缺点,通过倒转完成”成语不适合你(例如,如果你需要在其构造期间将列表传递给其他功能),那么还有“跟踪结束“技巧。然而,通过在其前面进行构建列表可能更清晰,然后在最终使用之前使用reverse或nreverse完成。

从本质上讲,这允许您在构建列表时以正确的顺序列出列表,但代价是需要跟踪它。

(defun track-tail (count)
  (let* ((list (cons 0 nil))
     (tail list))
    (loop for n from 1 below count
       do (progn
        (setf (cdr tail) (cons n nil))
        (setf tail (cdr tail))
        (format t "With n == ~d, the list is ~a~%" n list)))
    list))

这给出了以下输出:

CL-USER> (track-tail 5)
With n == 1, the list is (0 1)
With n == 2, the list is (0 1 2)
With n == 3, the list is (0 1 2 3)
With n == 4, the list is (0 1 2 3 4)
(0 1 2 3 4)

答案 2 :(得分:6)

您还没有指定Lisp的类型,因此如果您使用Emacs Lisp和dash列表操作库,它有一个函数-snoc,它返回一个新的列表,其中添加了元素结束。这个名字被颠倒了#34; cons"。

(-snoc '(1 2) 3) ; (1 2 3)

答案 3 :(得分:4)

你也可以使用nconc创建列表,就像追加一样,只修改输入列表的结构。

(nconc nlist (list (+ 2 2)))

答案 4 :(得分:3)

此函数在某些情况下可能很有用,它会透明地将单个元素附加到列表中,即它修改列表但返回附加元素(括在列表中):

(defun attach1 (lst x)
  (setf (cdr (last lst)) (cons x nil)))

;; (attach1 nlist (+ 2 2)) ; append without wrapping element to be added in a list

答案 5 :(得分:1)

使用此功能可以实现列表末尾的消息:

(defun cons-last (lst x)
  (let ((y (copy-list lst))) (setf (cdr (last y)) (cons x nil)) y))

;; (cons-last nlist (+ 2 2))

答案 6 :(得分:1)

如果您尝试添加两个列表,例如(1 2 3) + (1 2 3),则代码(递归)

(defun add-to-all (x y)
    (T (appendl (+ (first x) (first y)) (add-to-all (tail x) (tail y)) ))
)

如果您尝试将项目添加到第二个列表的末尾,例如3 + (1 2 3)

(defun add-to-all (x y)
  (cond ((null? y) nil)
    (T (appendl (+ (first x) (first y)) (add-to-all (tail x) (tail y)) ))
  )
)

答案 7 :(得分:1)

(追加l(列表e)); e是您要在列表尾部添加的元素

答案 8 :(得分:0)

如果您想在不更改该列表的情况下将项目添加到给定列表的末尾,那么如前所述,您可以使用类似

的功能
(defun annex (lst item)
  "Returns a new list with item added onto the end of the given list."
  (nconc (copy-list lst) (list item)))

这会返回一个新的扩展列表,同时保留输入列表。但是,如果要修改输入列表以包含添加的项目,则可以使用像

这样的宏
(define-modify-macro pushend (item)
  (lambda (place item)
    (nconc place (list item)))
  "Push item onto end of a list: (pushend place item).")
Pushend像推动一样运作,但是"推动"该项目在给定列表的末尾。另请注意,参数顺序与推动相反。