我有一个列表
'((1 2 (A B C)) (2 3 (B C D)) (4 5 (C D F)))
我想处理内部列表中的元素,(在本例中,我想将(A B C)
和其他列表更改为(M M M)
)。
我写了一个代码(process lst)
,它将为内部列表执行此任务。
(defun process (lst)
(cond
((null lst) '())
(T (cons 'M (process (cdr last))))))
当我从main函数调用时,
(defun iterate-list (lst)
(cond
((null lst) '())
((listp (car lst))
(cons (process (car lst))
(iterate-list (cdr lst))))
(T
(cons (car lst)
(iterate-list (cdr lst))))))
我得到的是((M M M) (M M M) (M M M))
而不是((1 2 (M M M)) (2 3 (M M M)) (4 5 (M M M)))
。
但是当我使用相同的函数时,在第二个条件(listp (car lst))
中只有(cons (car lst)) (iterate-list (cdr lst)))
,我得到了正确的答案,即
'((1 2 (A B C)) (2 3 (B C D)) (4 5 (C D F)))
我不知道我在哪里出错了。
如果你想要一些实用的,我建议从Common LISP Standard Library
.
subst
函数。http://clhs.lisp.se/Body/f_substc.htm
(setq tree1 '(1 (1 2) (1 2 3) (1 2 3 4))) => (1 (1 2) (1 2 3) (1 2 3 4))
(subst "two" 2 tree1) => (1 (1 "two") (1 "two" 3) (1 "two" 3 4))
(subst "five" 5 tree1) => (1 (1 2) (1 2 3) (1 2 3 4))
您还可以通过使用带有lambda函数的变体subst-if
来添加您自己的相等函数。
process
中的last
重命名为lst
。我得到((M M M M) (M M M M) (M M M M))而不是((1 2 (M M M M)) (2 3 (M M M M))) (4 5 (M M M M))
代码可以工作,但不是在你想要的深度:
(process '(a b c d))
=> (M M M M)
(iterate-list '(1 2 (A B C)))
=> (1 2 (M M M))
为了处理根列表中的所有列表,您可以这样做:
(mapcar #'iterate-list '((1 2 (A B C))
(2 3 (B C D))
(4 5 (C D F))))
=> ((1 2 (M M M)) (2 3 (M M M)) (4 5 (M M M)))