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

LISP新手求助:如何获取嵌套列表的平均长度?

如何用LISP获取嵌套列表的平均长度?

别担心,刚接触LISP的时候碰到这种嵌套列表的处理问题太正常了,我来一步步帮你拆解这个函数框架,搞清楚每个部分的逻辑,再帮你修正自己写的代码。

先明确需求

我们要实现的是:遍历外层列表,找出所有的子列表(跳过非列表元素),计算这些子列表的长度总和,再除以子列表的数量,最终得到平均长度(用浮点数展示结果更直观)。

拆解给定的函数框架

先把框架里的空位逐个填上,再逐一解释每个部分的逻辑:

(defun nested-lists-average-length (ls &aux (i 0) (n 0))
  ; dolist遍历ls里的每个元素a,循环结束后返回浮点数形式的平均值
  (dolist (a ls (float (/ i n))) 
    ; 判断当前元素a是不是列表(只处理子列表类型的元素)
    (if (listp a) 
        (progn 
          ; 把当前子列表的长度加到总和i里
          (incf i (length a)) 
          ; 子列表的计数n加1
          (incf n 1)))))

逐个解析空位的填充原因:

  1. dolist的返回值部分:(float (/ i n))——i是所有子列表长度的总和,n是子列表的总数量,用float把整数除法转成浮点数,避免只得到取整后的整数结果(比如总和5、数量2,直接/会得到2,float后会得到更准确的2.5)。
  2. (if (listp a))——listp是LISP里判断一个元素是否为列表的标准函数,我们只需要处理列表类型的子元素,非列表元素直接跳过。
  3. (incf i (length a))——incf是增量快捷函数,效果等同于(setq i (+ i (length a))),用来把当前子列表的长度累加到总和i中。
  4. (incf n 1)——每找到一个合格的子列表,就把计数n加1,统计子列表的总数量。

修正你自己写的函数

你写的代码方向是对的,但有两个关键问题需要调整:

  • 错误地用plusp判断元素:plusp是用来判断正数的,不是判断列表的,应该换成listp。
  • 未完成的(min...其实应该是获取子列表的长度(length x)。

修正后的完整版本:

(defun average-sublist-length (list &aux (sum 0) (n 0))
  ; 遍历每个元素x,当n大于0时返回平均值(避免外层无列表时出现除以0的错误)
  (dolist (x list (when (plusp n) (float (/ sum n))))
    ; 只处理列表类型的元素
    (when (listp x)
      ; 累加子列表长度到sum
      (incf sum (length x))
      ; 子列表计数加1
      (incf n 1))))

这里额外加了(when (plusp n))的判断,是为了避免外层列表里没有子列表时出现除以0的错误,此时函数会返回nil,逻辑更安全。

测试示例

用这个函数测试几个场景:

(nested-lists-average-length '((1 2) (3) "abc" (4 5 6)))
; 有效子列表是(1 2)(长度2)、(3)(长度1)、(4 5 6)(长度3),总和6,数量3,平均值2.0
; 返回结果:2.0

(average-sublist-length '((a b c) 123 (d)))
; 有效子列表长度总和3+1=4,数量2,平均值2.0
; 返回结果:2.0

内容的提问来源于stack exchange,提问作者Joe B Rock

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:57:16