我在表单的Common Lisp中有如下列表列表
((1 2) (3 4) (5 6))
和变量list
的值,我希望有三个新变量,其值是列表的元素。例如:
list-1 (1 2)
list-2 (3 4)
list-3 (5 6)
是否有任何功能可以执行此操作?
答案 0 :(得分:10)
(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
binds变量而不是assigning它们(即,它就像let
,而不是setq
)。
答案 1 :(得分:2)
将列表的元素绑定到list-#
形式的名称的概念可以推广。
您可以使用序数列表名称作为参数和给定正文创建一个生成lambda的函数:
(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)))
然后创建一个宏来创建lambda,编译它并将其应用到列表中:
(defmacro letlist (list &body body)
(let ((assignments (gensym)))
`(let ((,assignments ,list))
(apply (compile nil (make-list-lambda (length ,assignments) ',body))
,assignments))))
通过这种方式,赋值被本地化为lambda体:
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-#
个参数!
答案 2 :(得分:-1)
首先将列表设置为变量,例如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)
(第二个mylist)(最后一个mylist))
list-1(1 2)
list-2(3 4)
list-3((5 6))
零
[142]>
有人能告诉我如何在上面的输出中摆脱“NIL”吗?
我是Lisp的新手。只是为了好玩而学习。