list 将项目添加到列表末尾的“缺点”是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6439972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
what is the 'cons' to add an item to the end of the list?
提问by r b
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))
我有一个列表 (1 2 3) 并想向其中添加 4(其中 4 是评估的结果 (+ 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?
这表示 append 需要一个列表,而不是一个数字。我将如何做到这一点?
回答by danlei
You could use append, but beware that it can lead to bad performance if used in a loop or on very long lists.
您可以使用append,但请注意,如果在循环中或在很长的列表中使用它,可能会导致性能不佳。
(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).
回答by Vatine
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.
如果“前面的缺点,通过反转完成”习语不适合您(例如,如果您需要在构造过程中将列表传递给其他函数),那么还有“跟踪结束”诡计。但是,通过 consing 到它的前面来构建列表,然后在最终使用它之前使用 reverse 或 nreverse 完成它可能更干净。
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)
回答by Mirzhan Irkegulov
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".
您还没有指定 Lisp 的种类,所以如果您使用 Emacs Lisp 和dash
列表操作库,它有一个函数-snoc
返回一个新列表,其中添加了元素。名称倒转为“缺点”。
(-snoc '(1 2) 3) ; (1 2 3)
回答by Trey Hymanson
回答by mmj
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
回答by mmj
Cons-ing at the end of a list can be achieved with this function:
使用此函数可以实现列表末尾的 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))
回答by Giri
If you are trying to add two lists for example (1 2 3) + (1 2 3)
here is the code (recursive)
如果您尝试添加两个列表,例如(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)) ))
)
If you are trying to add an item to the end of the second list, for example 3 + (1 2 3)
例如,如果您尝试将项目添加到第二个列表的末尾 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)) ))
)
)
回答by Nadhem Jemmali
(append l (list e)) ; e is the element that you want to add at the tail of a list
(append l (list e)) ; e 是要添加到列表尾部的元素
回答by davypough
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.
Pushend 的操作类似于 push,但将项目“推”到给定列表的末尾。另请注意,参数顺序与推送相反。