1

我在表单的 Common Lisp 中有如下列表列表

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

这是变量的值list,我想要三个新变量,其值是列表的元素。例如:

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

有没有执行此操作的功能?

4

3 回答 3

10

使用setq, first(或nthand 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 绑定变量而不是分配它们(即,它是 like let,而不是 like setq)。

于 2012-12-31T18:44:10.043 回答
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-#在出​​现列表之前不知道会出现多少参数!

于 2013-01-02T07:01:49.313 回答
-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) (second mylist) (last mylist)) list-1 (1 2) list-2 (3 4) list-3 ((5 6)) NIL [142]> 有人可以告诉我如何摆脱“NIL”上面的输出?我是 Lisp 的新手。只是为了好玩而学习。

于 2013-11-30T19:21:10.027 回答