Определение элементов списка списка как новых переменных в общем lisp

65
4

У меня есть список списков в Common Lisp в форме

((1 2) (3 4) (5 6)) 

и который является значением list переменных, и я хочу иметь три новые переменные, значения которых являются элементами списка. Например:

list-1 (1 2)
list-2 (3 4)
list-3 (5 6)

Есть ли какая-либо функция, которая выполняет эту операцию?

спросил(а) 2021-01-19T14:23:18+03:00 9 месяцев назад
1
Решение
150

Используйте setq, first (или nth и elt), чтобы установить:

(setq list-1 (first list)
list-2 (second list)
list-3 (third list))

Или destructuring-bind для привязки:

(destructuring-bind (list-1 list-2 list-3) list
...)

Опять же, destructuring-bind связывает переменные вместо их назначения (т. setq Как let, а не как setq).

ответил(а) 2021-01-19T14:23:18+03:00 9 месяцев назад
79

Понятие привязывающих элементов списка к именам формы list-# можно обобщить.

Вы можете создать функцию для генерации лямбды с именами порядковых списков в качестве аргументов и заданного тела:

(defun make-list-lambda (n body)
(let ((list-names (loop for index from 1 to n
collect (intern (format nil "LIST-~D" index)))))
'(lambda ,list-names
(declare (ignorable ,@list-names))
,@body)))

А затем создайте макрос для создания лямбды, скомпилируйте его и примените его к списку:


(defmacro letlist (list &body body)
(let ((assignments (gensym)))
'(let ((,assignments ,list))
(apply (compile nil (make-list-lambda (length ,assignments) ',body))
,assignments))))

Таким образом, назначения локализуются в тело лямбда:

CL-USER> (letlist '(a b c d e f)
(format t "list-1: ~A~%" list-1)
(format t "list-3: ~A~%" list-3))
list-1: A
list-3: C
NIL

Примечание. Формы будут скомпилированы каждый раз при вызове макроса, так как не будет известно, сколько list-# аргументов будет присутствовать до тех пор, пока список не будет представлен!

ответил(а) 2021-01-19T14:23:18+03:00 9 месяцев назад
-5

Сначала установите свой список в переменную, например mylist. Затем вытолкните требуемый вывод, используя формат функции. Я использую CLISP. Надеюсь это поможет. Это фактический выход REPL.

(setf mylist '((1 2) (3 4) (5 6)) )

((1 2) (3 4) (5 6))

(format t "list-1 ~d~%list-2 ~d~%list-3 ~d" (car mylist) (второй список) (последний список)) list-1 (1 2) list-2 (3 4 ) list-3 ((5 6)) NIL [142]> Может кто-нибудь покажет мне, как избавиться от "NIL" в вышеприведенном выпуске? Я новичок в Lisp.

ответил(а) 2021-01-19T14:23:18+03:00 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема