打印带有中缀符号的列表

Jam*_*unn 3 lisp common-lisp

我想将s-表达式转换为带有前缀符号的字符串format。如何使用来完成format

例;

(format t "<insert format controls here>" (1 2 3) '*)
=> "1 * 2 * 3"
Run Code Online (Sandbox Code Playgroud)

cor*_*ump 7

此答案包含错误的代码。

简单,只需使用自定义格式器

(format t "~/acquire/~/disseminate/" '(1 2 3) '*)
Run Code Online (Sandbox Code Playgroud)

它们的定义如下:

(let ((memory))
  (defun cl-user::acquire (stream list &optional colonp atsignp)
    (declare (ignore colonp atsignp stream))
    (setf memory list))
  (defun cl-user::disseminate (stream operator &optional colonp atsignp)
    (declare (ignore colonp atsignp))
    (format stream (concatenate 'string "~{~a~^ " (string operator) " ~}") memory)
    (setf memory nil)))
Run Code Online (Sandbox Code Playgroud)

例如:

CL-USER> (format t "~/acquire/~/disseminate/" '(1 2 3) '*)
1 * 2 * 3
Run Code Online (Sandbox Code Playgroud)

memory变量是在这两者的功能,其允许它们进行通信数据的词法作用域。第一个存储列表,第二个使用列表。如果您从不调用第二个函数(或第一个带有nil的函数),memory永远将其绑定到最后一个列表,那可能是个问题。另请注意,您可能会遇到并发问题。坦白说,这不是您想要做的最好的方法,但是它可以根据您的要求完成工作。

  • 让`超过`lambda`很酷。让`defun`上的`let':不多。 (2认同)

Gwa*_*Kim 5

(format t "~{~A~^ * ~}" '(1 2 3))
;; 1 * 2 * 3
;; NIL
Run Code Online (Sandbox Code Playgroud)
  • ~{~}:循环遍历列表。
  • ~A:打印人可读(一个审美)
  • ~^:仅当列表中有后继元素时才打印以下内容。
  • *:在周围的空白处加缀。

我曾经问过类似的问题。您'*在最后添加了-因此您还希望控制join列表元素应使用哪个分隔符。查看以下链接-@Sylwester给出了可接受的答案:common-lisp中的pythonic`join`

(他通过将第二个格式表达式注入格式表达式来做到这一点-非常优雅!-这样就可以调用(join '(1 2 3) :sep " * "))。