【问题标题】:How to remove a list of length 1 from a nested list in lisp?如何从 lisp 的嵌套列表中删除长度为 1 的列表?
【发布时间】:2020-02-29 04:13:06
【问题描述】:

我有一个嵌套列表 (1 (4 (5) 3) 9 10),我想删除长度为 1 的列表,因此结果将是 (1 (4 3) 9 10)。 这是我迄今为止尝试过的,它不会删除 (5) 并返回原始列表。

(defun remove (l)
(cond
    ((null l) nil)   
    ((and (listp (car l)) (= (length l) 1)) (remove (cdr l)))   
    ((atom (car l)) (cons (car l) (remove (cdr l))))
    (T (cons (remove (car l)) (remove (cdr l))))   
))

【问题讨论】:

    标签: recursion lisp common-lisp nested-lists


    【解决方案1】:

    两件事:首先,remove 是 CL 包中的预定义函数,所以我强烈建议使用不同的名称,比如my-remove。 其次,您正在测试l 的长度,而不是您想要消除的子列表(car l)。 正确的形式是:

    (defun my-remove (l)
      (cond
        ((null l) nil)   
        ((and (listp (car l)) (= (length (car l)) 1)) (my-remove (cdr l)))   
        ((atom (car l)) (cons (car l) (my-remove (cdr l))))
        (T (cons (my-remove (car l)) (my-remove (cdr l))))   
    ))
    

    【讨论】:

      【解决方案2】:

      尾调用递归版本。另外:没有测试(atom (car l)) 允许列表中的非列表和非原子组件。 (例如,向量或其他对象作为列表的元素 - 它们被视为原子。

      (defun my-remove (l &optional (acc '()))
        (cond ((null l) (nreverse acc))
              ((listp (car l)) (if (= 1 (length (car l)))         ;; list objects
                                   (my-remove (cdr l) acc)        ;; - of length 1     
                                   (my-remove (cdr l) (cons (my-remove (car l)) acc)))) ;; - longer
              (t (my-remove (cdr l) (cons (car l) acc)))))        ;; non-list objects
      

      【讨论】:

        猜你喜欢
        • 2019-07-13
        • 2017-06-03
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多