Что такое "минусы", чтобы добавить элемент в конец списка?

Каков типичный способ добавления элемента в конец списка?

У меня есть список (1 2 3) и хочу добавить к нему 4 (где 4 - результат оценки (+ 2 2))

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

Это говорит о том, что append ожидает список, а не число. Как бы это сделать?

Ответ 1

Вы можете использовать append, но будьте осторожны, что это может привести к плохой производительности при использовании в цикле или в очень длинном списке.

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

Если производительность важна, обычная идиома - это сбор списков путем добавления (используя cons), затем reverse (или nreverse).

Ответ 2

Вы не указали тип Lisp, поэтому, если вы используете библиотеки управления списками Emacs Lisp и dash, он имеет функцию -snoc, которая возвращает новый список с добавленным элементом до конца. Имя изменено на "cons".

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

Ответ 3

Если "cons in the front, finish by reversing" idiom вам не подходит (если вам, например, нужно передать список другим функциям ВО ВРЕМЯ его построения), там также "отслеживать" конец "трюка. Тем не менее, возможно, более чистое, чтобы просто создать список, обратившись к нему, затем закончите с помощью обратного или 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)

Ответ 4

Вы также можете использовать nconc, чтобы создать список, похожий на append, только он изменяет структуру входных списков.

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

Ответ 5

Эта функция может быть полезна в некоторых ситуациях, она прозрачно добавляет один элемент в список, т.е. изменяет список, но возвращает добавленный элемент (заключенный в список):

(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

Ответ 6

Консолидация в конце списка может быть достигнута с помощью этой функции:

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

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

Ответ 7

Если вы пытаетесь добавить два списка, например (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)) ))
  )
)

Ответ 8

(добавить l (список e)); e - это элемент, который вы хотите добавить в хвост списка