You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lisp中Lambda内assoc未求值:如何用mapcar重置书籍分数为0

LISP中使用mapcar和lambda重置书籍score的问题

数据结构定义

用户定义了如下书籍列表数据结构:

(setf *books* '(
        (
            (:tit 'Titulo1)
            (:aut (quote Autor1))
            (:gen 'Genero1)
            (:score 99)
        )
        (
            (:tit 'Titulo2)
            (:aut (quote Autor2))
            (:gen 'Genero2)
            (:score 40)
        )
))

需求与问题代码

需求是通过mapcar和lambda将所有书籍的score字段重置为0,用户尝试编写的reset函数如下:

(defun reset(list)
    (mapcar
        (lambda(libro)
            '(
                (:tit (assoc :puntuacion libro))
                (:aut (assoc :aut libro))
                (:gen (assoc :gen libro))
                (:score 0)
            )
        )
        list
    )
)

这段代码的核心问题:

  1. 用单引号'包裹返回列表,导致列表内所有表达式都被当作字面量,assoc函数完全不会被求值,直接返回符号本身。
  2. 错误使用:puntuacion作为键,原数据结构中对应的键是:tit。
  3. 即便assoc被求值,它返回的是完整键值对(如(:tit 'Titulo1)),而非对应的值,需要额外提取值部分。

正确实现方式

使用**反引号`**构建模板列表,配合逗号,插入求值结果,同时修正键名并提取assoc返回的值:

(defun reset (book-list)
  (mapcar (lambda (libro)
            `((:tit ,(cadr (assoc :tit libro)))
              (:aut ,(cadr (assoc :aut libro)))
              (:gen ,(cadr (assoc :gen libro)))
              (:score 0)))
          book-list))

代码说明:

  • 反引号`创建模板列表,普通元素保持字面量,逗号,后的表达式会被求值并插入列表。
  • (assoc :tit libro)找到单本书籍中:tit对应的键值对,cadr用于取出该键对应的值(如'Titulo1)。
  • 修正键名错误,将:puntuacion改为:tit,匹配原数据结构的字段。

调用(reset *books*)会返回所有score重置为0的新书籍列表,原*books*列表不会被修改(LISP列表默认不可变,mapcar返回新列表)。

内容的提问来源于stack exchange,提问作者Jose A. Matarán

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:27:24