Formatting 如何在common lisp中格式化列表?

Formatting 如何在common lisp中格式化列表?,formatting,lisp,format,common-lisp,string-formatting,Formatting,Lisp,Format,Common Lisp,String Formatting,我开始给我写一些常见的Lisp,我刚刚掌握了把事情考虑在一起并格式化它们的窍门 让我们假设我有一个列表,如下所示: (defvar *map* '((0 . "zero") (1 . "one") (2 . "two"))) (loop for (a . b) in *mapping* do (format t "~a: ~a" a b)) 我怎么把它格式化成这样 0: zero 1: one 2: two 我想的是类似于(格式t“~{{~a:~a~}~%~}”*map*),但这会产生

我开始给我写一些常见的Lisp,我刚刚掌握了把事情考虑在一起并格式化它们的窍门

让我们假设我有一个列表,如下所示:

(defvar *map* '((0 . "zero") (1 . "one") (2 . "two")))
(loop for (a . b) in *mapping*
  do (format t "~a: ~a" a b))
我怎么把它格式化成这样

0: zero
1: one
2: two
我想的是类似于
(格式t“~{{~a:~a~}~%~}”*map*)
,但这会产生一个错误,因为“zero”不是一个列表,你不能使用它

当然,执行
(格式t“~{~a~%~}”*map*)
打印

(0 . "zero")
(1 . "one")
(2 . "two")

就像我想的那样,但这不是我想要的。有没有更好的方法可以做到这一点,而不仅仅是
(dolist(entry*mapping*)(格式t“~a:~a~%”(carentry)(cdr entry))

我认为没有更好的方法;我会使用
map()


你是对的,因为看起来没有任何方法可以从格式中区分cons单元格

如果定义另一个函数来格式化单个关联:

(defun print-assoc (stream arg colonp atsignp)
  (format stream "~A: ~A" (car arg) (cdr arg)))
那么很容易:

(format t "~{~/print-assoc/~%~}" *map*)
我不确定这是否是一种进步。一方面,它有点复杂,但另一方面,它确实将print assoc分解为一个(可重用)函数,这可能很有用。

Freenode上的#cl gardeners频道建议执行如下解构循环绑定:

(defvar *map* '((0 . "zero") (1 . "one") (2 . "two")))
(loop for (a . b) in *mapping*
  do (format t "~a: ~a" a b))

我认为这里的外卖教训是,不要为你的主义者使用虚线列表。当然,您保存了一个cons单元格,但放弃了所有漂亮的序列和列表函数。这不值得。对于完全格式的列表,您的格式示例很简单:

(defvar *map* '((0 "zero") (1 "one") (2 "two")))
(format t "~:{~a: ~a~}" *map*)

使用将列表单元格
(a.2)
转换为列表
(a.2)

(mapcar #'(lambda (x) `(,(car x) ,(cdr x))) *map*)
然后以格式进行处理

例如,将
((a.2)(b.3))打印为
“a=2&b=3”

使用


您应该在格式中使用限定函数名。FORMAT解析包中指定的符号,在调用FORMAT时,您永远不会知道包是什么。