что такое «минусы», чтобы добавить элемент в конец списка? - PullRequest
13 голосов
/ 22 июня 2011

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

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

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

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

Ответы [ 9 ]

27 голосов
/ 22 июня 2011

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

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

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

6 голосов
/ 06 августа 2014

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

(-snoc '(1 2) 3) ; (1 2 3)
6 голосов
/ 26 июня 2011

Если идиома «минусы впереди, финиширование задним ходом» не подходит вам (если вам, например, нужно передать список другим функциям во время его создания), есть также «отслеживать» конец "трюк. Тем не менее, возможно, будет проще построить список, поместив его в начало, а затем завершить, используя 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)
4 голосов
/ 22 июня 2011

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

(nconc nlist (list (+ 2 2)))
3 голосов
/ 16 апреля 2012

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

(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
1 голос
/ 14 марта 2017

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

1 голос
/ 04 декабря 2014

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

С помощью этой функции можно получить информацию о конце списка:

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

;; (cons-last nlist (+ 2 2))
0 голосов
/ 12 июня 2018

Если вы хотите добавить элемент в конец данного списка без изменения этого списка, то, как ранее предлагалось, вы можете использовать функцию, такую ​​как

(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 работает как push, но «выталкивает» элемент в конец данного списка. Также обратите внимание, что порядок аргументов является обратным толчку.

...