Создание cons-ячеек и списков
Многие функции создают списки, поскольку списки лежат в самой основе Lisp. cons — основная функция для создания списков; однако интересно отметить, что list используется в исходном коде Emacs чаще, чем cons.
- Функция: cons object1 object2
-
Эта функция является наиболее простой функцией для создания новой структуры списка. Она создаёт новую cons-ячейку, помещая object1 в CAR, а object2 — в CDR. Затем она возвращает новую cons-ячейку. Аргументами object1 и object2 могут быть любые объекты Lisp, но чаще всего object2 — это список.
(cons 1 '(2)) ⇒ (1 2)(cons 1 '()) ⇒ (1)(cons 1 2) ⇒ (1 . 2)consчасто используется для добавления одного элемента в начало списка. Это называется добавлением элемента в список с помощью cons. Например:(setq list (cons newelt list))
Обратите внимание, что между переменной с именем
list, использованной в этом примере, и функцией с именемlist, описанной ниже, нет конфликта; любой символ может использоваться в обеих ролях.
- Функция: list &rest objects
-
Эта функция создаёт список, элементами которого являются objects. Результирующий список всегда завершается
nil. Если аргументы objects не заданы, возвращается пустой список.(list 1 2 3 4 5) ⇒ (1 2 3 4 5)(list 1 2 '(3 4 5) 'foo) ⇒ (1 2 (3 4 5) foo)(list) ⇒ nil
- Функция: make-list length object
-
Эта функция создаёт список из length элементов, каждый из которых равен object. Сравните
make-listсmake-string(см. Создание строк).(make-list 3 'pigs) ⇒ (pigs pigs pigs)(make-list 0 'pigs) ⇒ nil(setq l (make-list 3 '(a b))) ⇒ ((a b) (a b) (a b)) (eq (car l) (cadr l)) ⇒ t
- Функция: append &rest sequences
-
Эта функция возвращает список, содержащий все элементы sequences. Аргументами sequences могут быть списки, векторы, булевы векторы или строки, но последний аргумент обычно должен быть списком. Все аргументы, кроме последнего, копируются, поэтому ни один из аргументов не изменяется. (О способе объединения списков без копирования см.
nconcв разделе Функции перестановки списков.)В более общем случае последний аргумент
appendможет быть любым объектом Lisp. Последний аргумент не копируется и не преобразуется; он становится CDR последней cons-ячейки нового списка. Если последний аргумент сам является списком, его элементы фактически становятся элементами результирующего списка. Если последний аргумент не является списком, результатом будет точечный список, поскольку его последний CDR не равенnil, как того требует правильный список (см. Списки и cons-ячейки).
Пример использования append:
(setq trees '(pine oak))
⇒ (pine oak)
(setq more-trees (append '(maple birch) trees))
⇒ (maple birch pine oak)
trees
⇒ (pine oak)
more-trees
⇒ (maple birch pine oak)
(eq trees (cdr (cdr more-trees)))
⇒ t
Работу append можно увидеть на диаграмме-боксах. Переменной trees присваивается список (pine oak), а затем переменной more-trees присваивается список (maple birch pine
oak). Однако переменная trees продолжает ссылаться на исходный список:
more-trees trees
| |
| --- --- --- --- -> --- --- --- ---
--> | | |--> | | |--> | | |--> | | |--> nil
--- --- --- --- --- --- --- ---
| | | |
| | | |
--> maple -->birch --> pine --> oak
Пустая последовательность не влияет на значение, возвращаемое append. Поэтому последний аргумент nil приводит к копированию предыдущего аргумента:
trees
⇒ (pine oak)
(setq wood (append trees nil))
⇒ (pine oak)
wood
⇒ (pine oak)
(eq wood trees)
⇒ nil
Раньше это был обычный способ копирования списка, пока не появилась функция copy-sequence. См. Последовательности, массивы и векторы.
Далее показано использование векторов и строк в качестве аргументов append:
(append [a b] "cd" nil)
⇒ (a b 99 100)
Преобразовать строку в список её символов можно так:
(append "abcd" nil)
⇒ (97 98 99 100)
Функция string-to-list — удобное сокращение для приведённого выше способа.
С помощью apply (см. Вызов функций) можно объединить все списки, входящие в список списков:
(apply 'append '((a b c) nil (x y z) nil))
⇒ (a b c x y z)
Если аргументы sequences не заданы, возвращается nil:
(append)
⇒ nil
Вот несколько примеров, в которых последний аргумент не является списком:
(append '(x y) 'z)
⇒ (x y . z)
(append '(x y) [z])
⇒ (x y . [z])
Второй пример показывает, что если последний аргумент является последовательностью, но не списком, элементы последовательности не становятся элементами результирующего списка. Вместо этого последовательность становится последним CDR, как и любой другой последний аргумент, не являющийся списком.
Исключение: если все аргументы, кроме последнего, равны nil, а последний аргумент не является списком, возвращаемым значением будет этот последний аргумент без изменений (то есть в этом случае возвращаемое значение не является списком):
(append nil nil "abcd")
⇒ "abcd"
- Функция: copy-tree tree &optional vectors-and-records
-
Эта функция возвращает копию дерева tree. Если tree является cons-ячейкой, создаётся новая cons-ячейка с теми же CAR и CDR, после чего CAR и CDR рекурсивно копируются таким же образом.
Обычно, если tree не является cons-ячейкой,
copy-treeпросто возвращает tree. Однако, если vectors-and-records не равноnil, копируются также векторы и записи (и их элементы обрабатываются рекурсивно). Аргумент tree не должен содержать циклов.
- Функция: flatten-tree tree
Эта функция возвращает «уплощённую» копию tree, то есть список, содержащий все конечные узлы, или листья, дерева cons-ячеек с корнем в tree, не равные
nil. Листья в возвращаемом списке расположены в том же порядке, что и в tree.
(flatten-tree '(1 (2 . 3) nil (4 5 (6)) 7))
⇒(1 2 3 4 5 6 7)
- Функция: ensure-list object
-
Эта функция возвращает object в виде списка. Если object уже является списком, функция возвращает его; в противном случае функция возвращает одноэлементный список, содержащий object.
Обычно это полезно, если у вас есть переменная, которая может быть списком, а может и не быть, и тогда можно, например, написать:
(dolist (elem (ensure-list foo)) (princ elem))
- Функция: ensure-proper-list object
-
Эта функция возвращает object в виде правильного списка (см. (elisp)Cons-ячеек). Если object уже является правильным списком, функция возвращает его; в противном случае функция возвращает одноэлементный список, содержащий object.
Если object может быть длинным списком, предпочтительнее использовать
ensure-list, поскольку эта функция выполняется за постоянное время, тогда какensure-proper-listвыполняется за линейное время. Для коротких списков эта функция удобна, чтобы обрабатывать cons-ячейки как объекты, не являющиеся списками:(ensure-list '(1 . 2)) ⇒(1 . 2) (ensure-proper-list '(1 . 2)) ⇒((1 . 2))
- Функция: number-sequence from &optional to separation
-
Эта функция возвращает список чисел, начинающийся с from, увеличивающийся с шагом separation и заканчивающийся на to или непосредственно перед ним. Значение separation может быть положительным или отрицательным; по умолчанию оно равно 1. Если to равен
nilили численно равен from, результатом будет одноэлементный список(from). Если to меньше from при положительном значении separation или больше from при отрицательном значении separation, результатом будетnil, поскольку эти аргументы задают пустую последовательность.Если separation равно 0, а to не равно
nilи численно не равно from,number-sequenceсигнализирует об ошибке, поскольку такие аргументы задают бесконечную последовательность.Все аргументы должны быть числами. Аргументы с плавающей точкой могут вызывать затруднения, поскольку арифметика с плавающей точкой неточна. Например, в зависимости от машины вполне может оказаться, что
(number-sequence 0.4 0.6 0.2)возвращает одноэлементный список(0.4), тогда как(number-sequence 0.4 0.8 0.2)возвращает список из трёх элементов. Элемент списка с номером n вычисляется по точной формуле(+ from (* n separation)). Поэтому, если необходимо гарантировать включение to в список, можно передать для to выражение именно такого вида. Также можно заменить to немного большим значением (или немного более отрицательным значением, если separation отрицательно).Несколько примеров:
(number-sequence 4 9) ⇒ (4 5 6 7 8 9) (number-sequence 9 4 -1) ⇒ (9 8 7 6 5 4) (number-sequence 9 4 -2) ⇒ (9 7 5) (number-sequence 8) ⇒ (8) (number-sequence 8 5) ⇒ nil (number-sequence 5 8 -1) ⇒ nil (number-sequence 1.5 6 2) ⇒ (1.5 3.5 5.5)
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Building-Lists.html