用于确定列表中嵌套列表长度的 Common Lisp 函数
Common Lisp function to determine lengths of nested lists in a list
我只被允许使用 do
构造,我仍然无法理解的概念。我尝试了以下代码,但它 returns nil
.
(defun fun(list)
(do ((i 0 (+ i 1)) (l '() (if (listp (nth i list)) (append l (list (length (nth i list)))))))
((null (nth i list)) l)
)
)
l
的更新值有误吗?此列表 (a (b) (c d))
的输出应为 (1 2)
。
尝试用列表而不是数组来思考。您正在使用列表的第 n 个元素,就好像它是一个数组一样。相反,使用 do
您可以通过每次获取下一个子列表来遍历列表,即删除第一个元素并获取另一个没有第一个元素的列表。
(defun fun(list)
(do ((l list (cdr l))
(result nil) )
((null l) (nreverse result))
(if (listp (car l))
(push (length (car l)) result) )))
do
运算符采用三个参数:变量列表、结束条件和循环体。第一个包括变量的名称、它们的初始值以及(可选)它们如何从一个循环变为下一个循环。例如,(l list (cdr l))
表示您使用一个变量 l
,其初始值为输入列表,并且从一个循环到下一个循环它将成为其自身的 cdr,即它将丢失其第一个元素。
结束条件还包括函数的 return 值。使用 ((null l) (nreverse result))
我们是说当变量 l
为 null 时,函数将结束并且 return 值为 (nreverse result)
。为什么不反转?因为我们在 body 中使用了 push,它以错误的顺序累积值。
最后,当这是一个列表时,正文告诉函数将 l
的第一个元素的长度添加到 result
。
遍历 nested-list
中的所有项目。对每一个按照listp
为list的,计算长度,收集起来。收集到的长度列表就是结果值:
(loop for item in nested-list
if (listp item) collect (length item))
将每个元素 nested-list
传递到一个函数中。对于列表中的每个项目,函数 returns 一个长度的单元素列表,否则它 returns 空列表。这些列表被串联成一个列表,并返回。
(mapcan (lambda (x) (if (listp x) (list (length x)))) nested-list)
从 nested-list
中删除非列表项,生成一个只有列表的新列表。然后通过length
函数映射这个列表,得到长度列表:
(mapcar #'length (remove-if-not #'listp nested-list))
我只被允许使用 do
构造,我仍然无法理解的概念。我尝试了以下代码,但它 returns nil
.
(defun fun(list)
(do ((i 0 (+ i 1)) (l '() (if (listp (nth i list)) (append l (list (length (nth i list)))))))
((null (nth i list)) l)
)
)
l
的更新值有误吗?此列表 (a (b) (c d))
的输出应为 (1 2)
。
尝试用列表而不是数组来思考。您正在使用列表的第 n 个元素,就好像它是一个数组一样。相反,使用 do
您可以通过每次获取下一个子列表来遍历列表,即删除第一个元素并获取另一个没有第一个元素的列表。
(defun fun(list)
(do ((l list (cdr l))
(result nil) )
((null l) (nreverse result))
(if (listp (car l))
(push (length (car l)) result) )))
do
运算符采用三个参数:变量列表、结束条件和循环体。第一个包括变量的名称、它们的初始值以及(可选)它们如何从一个循环变为下一个循环。例如,(l list (cdr l))
表示您使用一个变量 l
,其初始值为输入列表,并且从一个循环到下一个循环它将成为其自身的 cdr,即它将丢失其第一个元素。
结束条件还包括函数的 return 值。使用 ((null l) (nreverse result))
我们是说当变量 l
为 null 时,函数将结束并且 return 值为 (nreverse result)
。为什么不反转?因为我们在 body 中使用了 push,它以错误的顺序累积值。
最后,当这是一个列表时,正文告诉函数将 l
的第一个元素的长度添加到 result
。
遍历 nested-list
中的所有项目。对每一个按照listp
为list的,计算长度,收集起来。收集到的长度列表就是结果值:
(loop for item in nested-list
if (listp item) collect (length item))
将每个元素 nested-list
传递到一个函数中。对于列表中的每个项目,函数 returns 一个长度的单元素列表,否则它 returns 空列表。这些列表被串联成一个列表,并返回。
(mapcan (lambda (x) (if (listp x) (list (length x)))) nested-list)
从 nested-list
中删除非列表项,生成一个只有列表的新列表。然后通过length
函数映射这个列表,得到长度列表:
(mapcar #'length (remove-if-not #'listp nested-list))