lisp - 如何从列表中删除子列表?
问题描述
我想从我的列表中删除一个特殊列表。但是功能 remove 并不能帮助我解决这个问题。
它用于在列表中进行深度搜索,我想把它扔掉。我尝试使用功能删除,但它不起作用。
(DEFPARAMETER WB '((HALLWAY EAST OFFICE) (OFFICE WEST HALLWAY) (OFFICE NORTH KITCHEN) (KITCHEN SOUTH OFFICE) (BEDROOM WEST GARDEN) (GARDEN EAST BEDROOM) (GARDEN WEST OFFICE) (OFFICE EAST GARDEN) (GARDEN NORTH BATHROOM) (BATHROOM SOUTH GARDEN) (LAVATORY SOUTH BEDROOM) (BEDROOM NORTH LAVATORY) (LAVATORY WEST BATHROOM) (BATHROOM EAST LAVATORY) (BATHROOM WEST KITCHEN) (KITCHEN EAST BATHROOM) (STUDIO EAST KITCHEN) (KITCHEN WEST STUDIO) (STUDIO SOUTH HALLWAY) (HALLWAY NORTH STUDIO)))
(REMOVE '(BATHROOM EAST KITCHEN) WB) ;should throw (BATHROOM EAST KITCHEN) out of WB but does not work
(REMOVE '(1 2 3) '((4 5 6) (1 2 3)))
My expected result is ((4 5 6))
But the output is ((4 5 6) (1 2 3))
解决方案
:test
关键字参数的默认值REMOVE
(以及更普遍的接受测试函数参数的函数)是EQL
.
当您编写时(remove '(1 2 3) '((1 2 3) (4 5 6)))
,您无法保证打印为的两个列表(1 2 3)
是相同的。它们可能由不同的 cons 单元格表示:
(eql '(1 2 3) '(1 2 3))
=> NIL
编译器可以在编译时检测到两个列表相等并使用相同的底层内存,使它们成为 EQ,但您通常不能假设是这种情况。
但是,如果您使用了两次相同的列表,REMOVE
则会按预期工作:
(let ((a '(1 2 3))) (remove a (list a '(4 5 6))))
=> ((4 5 6))
上面的示例也可以使用 reader 变量编写如下(结果相似,但整个列表被引用而不是在运行时创建list
):
(remove '#1=(1 2 3) '(#1# (4 5 6)))
=> ((4 5 6))
在一般情况下,当您不通过身份来操作对象时,您需要使用知道如何比较列表的测试函数,以便具有相同内容的不同列表被认为是相等的:
(remove '(1 2 3) '((1 2 3) (4 5 6)) :test #'equal)
=> ((4 5 6))
使用上面的代码,元素与EQUAL
.
推荐阅读
- php - 如何使用带有 foreach 循环的 php 进行行跨度
- javascript - 我在导入此文件时遇到问题
- python - 如何在前端以百分比形式显示搜索结果分数?
- python - 如何让 matplotlib 处理自定义类“单位”
- google-cloud-functions - 如何优化从 HTTP 触发函数并行调用“子”云函数
- memory - C/C++ 中本地函数的内存填充和对齐
- c# - WinForms - 加载表单时如何使用 PaintEventArgs 运行函数?
- python-3.x - def 函数比较两个字符串
- python - Python 多个 onclick 事件
- assembly - 如何在特定列打印包含多行的整个字符串?