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

发布于 2024-11-16 15:40:43 字数 193 浏览 2 评论 0原文

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

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

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

这表示追加需要一个列表,而不是数字。我将如何实现这个目标?

what's the typical way to add an item to the end of the list?

I have a list (1 2 3) and want to add 4 to it (where 4 is the result of an evaluation (+ 2 2))

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

This says that append expects a list, not a number. How would I accomplish this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

酒解孤独 2024-11-23 15:40:43

您可以使用 append,但请注意,如果用于循环或非常长的列表。

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

如果性能很重要,通常的习惯用法是通过前置构建列表(使用 cons),然后反向 (或nreverse)。

You could use append, but beware that it can lead to bad performance if used in a loop or on very long lists.

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

If performance is important, the usual idiom is building lists by prepending (using cons), then reverse (or nreverse).

也只是曾经 2024-11-23 15:40:43

如果“前面的缺点,通过反转完成”习惯用法不适合您(例如,如果您需要在构建过程中将列表传递给其他函数),那么还有“跟踪末尾”诡计。然而,通过 cons 到列表的前面来构建列表,然后在最终使用它之前使用反向或 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)

If the "cons at the front, finish by reversing" idiom isn't suitable for you (if you. for example, need to pass the list on to other functions DURING its construction), there's also the "keep track of the end" trick. However, it's probably cleaner to just build the list by consing to the front of it, then finish by using reverse or nreverse before finally using it.

In essence, this allows you to have the list in the right order while building it, at the expense of needing to keep track of it.

(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))

This gives the following output:

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)
妳是的陽光 2024-11-23 15:40:43

您还可以使用 nconc 来创建列表,类似于追加,只是它修改了输入列表的结构。

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

You can also use nconc to create the list, which is like append, only it modifies the structure of the input lists.

(nconc nlist (list (+ 2 2)))
狂之美人 2024-11-23 15:40:43

您还没有指定 Lisp 的类型,因此如果您使用 Emacs Lisp 和 dash 列表操作库,它有一个函数 -snoc 返回一个新列表,并将元素添加到末尾。这个名字是反写的“cons”。

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

You haven't specified the kind of Lisp, so if you use Emacs Lisp and dash list manipulation library, it has a function -snoc that returns a new list with the element added to the end. The name is reversed "cons".

(-snoc '(1 2) 3) ; (1 2 3)
逐鹿 2024-11-23 15:40:43

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

(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

This function might be useful in some situations, it transparently appends a single element to a list, i.e. it modifies the list but returns the appended element (enclosed in a list):

(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
暖树树初阳… 2024-11-23 15:40:43

(附加l(列表e)); e 是要添加到列表尾部的元素

(append l (list e)) ; e is the element that you want to add at the tail of a list

执笏见 2024-11-23 15:40:43

列表末尾的 Cons-ing 可以通过以下函数实现:

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

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

Cons-ing at the end of a list can be achieved with this function:

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

;; (cons-last nlist (+ 2 2))
烟─花易冷 2024-11-23 15:40:43

如果您尝试添加两个列表,例如 (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)) ))
  )
)

If you are trying to add two lists for example (1 2 3) + (1 2 3) here is the code (recursive)

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

If you are trying to add an item to the end of the second list, for example 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)) ))
  )
)
是你 2024-11-23 15:40:43

如果您想将一个项目添加到给定列表的末尾而不更改该列表,那么按照前面的建议,您可以使用类似

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

This 返回一个新的扩展列表的函数,同时保留输入列表。但是,如果您想修改输入列表以包含添加的项目,那么您可以使用像

(define-modify-macro pushend (item)
  (lambda (place item)
    (nconc place (list item)))
  "Push item onto end of a list: (pushend place item).")

Pushend 这样的宏,其操作类似于推送,但将项目“推”到给定列表的末尾。另请注意,参数顺序与推送顺序相反。

If you want to add an item onto the end of a given list without changing that list, then as previously suggested you can use a function like

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

This returns a new extended list, while preserving the input list. However, if you want to modify the input list to include the added item, then you can use a macro like

(define-modify-macro pushend (item)
  (lambda (place item)
    (nconc place (list item)))
  "Push item onto end of a list: (pushend place item).")

Pushend operates like push, but "pushes" the item onto the end of the given list. Also note the argument order is the reverse of push.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文