我有一个基本的clisp函数,我只是返回列表中的原子数。我遇到的问题是我需要它来增加列表中列表中的原子,而不是将列表视为列表中的1个元素。
我猜的真正问题是如何在代码中区分元素是列表还是原子?如果我可以这样做,我可以将列表发送到另一个函数来添加并返回它们包含的原子数。
清除泥土? :)
我在这里有一个例子:
(defun list_length (a)
(cond ((null a) 0)
(t (+ 1 (list_length (cdr a))))))
如果父列表中没有嵌入列表,这很有用,例如,
'(1 2 3 (4 5) 6)
将返回5.我需要它包含4和5而不是列表(4 5)作为一个。
感谢您的帮助。
乔恩
编辑:
(defun list_length (a)
(cond ((null a) 0)
((listp (car a)) (list_length (car a)))
(t (+ 1 (list_length (cdr a))))))
[18]> (list_length '(1 2 3 (4 5) 6))
1. Trace: (LIST_LENGTH '(1 2 3 (4 5) 6))
2. Trace: (LIST_LENGTH '(2 3 (4 5) 6))
3. Trace: (LIST_LENGTH '(3 (4 5) 6))
4. Trace: (LIST_LENGTH '((4 5) 6))
5. Trace: (LIST_LENGTH '(4 5))
6. Trace: (LIST_LENGTH '(5))
7. Trace: (LIST_LENGTH 'NIL)
7. Trace: LIST_LENGTH ==> 0
6. Trace: LIST_LENGTH ==> 1
5. Trace: LIST_LENGTH ==> 2
4. Trace: LIST_LENGTH ==> 2
3. Trace: LIST_LENGTH ==> 3
2. Trace: LIST_LENGTH ==> 4
1. Trace: LIST_LENGTH ==> 5
5
[19]> (dribble)
答案 0 :(得分:4)
(listp foo)
是列表,则 t
将返回foo
,否则将返回nil
。
因此,您可以通过向list_length
添加以下案例来使cond
函数处理嵌套列表:
((listp (car a)) (+ (list_length (car a)) (list_length (cdr a))))
答案 1 :(得分:3)
ATOM是您要求的谓词。
我建议使用FLATTEN,一个标准例程来压缩列表中的列表 - 我在这里提出了一个实现。
(defun flatten (x)
"descend into the supplied list until an atom is hit.
append the atom to the flattened rest"
(if (endp x)
x
(if (atom (car x ))
(append (list (car x)) (flatten (cdr x)))
(append (flatten (car x)) (flatten (cdr x ))))))
Flatten返回一个列表:您可以在列表中运行LENGTH以查看您最多关闭了多少个ATOMS。