我是lisp的新手并且正在处理作业问题以展平嵌套列表。我有我的功能工作,除了它需要'删除'点对。所以给定(1(2 3)(4.5)((6 7)(89)))我的函数应输出(1 2 3 4 5 6 7 8 9)。
所以..我的实际问题..
如果有一对虚线对,例如(1 . 2)
,我该如何获取列表'(1 2)
?
答案 0 :(得分:7)
cons单元是一个由两部分组成的结构,称为car
及其cdr
。对(1 . 2)
是一个缺点单元格,其car
为1
且其cdr
为2
。 Lisps中的列表是由cons单元格nil
构建的。如何在多个地方描述其工作原理,包括Recursive range in Lisp adds a period?的答案。列表是空列表()
(也称为nil
),或者是car
的利弊是列表的第一个元素,其cdr
是另一个列表,列表的其余部分。这意味着一个列表
(1 2)
由缺点单元格构建,nil
为
(cons 1 (cons 2 nil))
如果您已经(1 . 2)
,那么您可以1
和2
获得car
和cdr
。如上所述,你将它们重新组合在一起。也就是说,
(let ((x '(1 . 2)))
(cons (car x) (cons (cdr x) nil)))
或者,您可以使用list
:
(let ((x '(1 . 2)))
(list (car x) (cdr x)))
如果您想重复使用相同的cons单元格,则可以使用cdr
替换单元格的(cons 2 nil)
。例如(并注意我们不再引用该对,因为修改文字数据是未定义的行为):
(let ((x (cons 1 2)))
(setf (cdr x) (cons (cdr x) nil))
x)
那也可能是
(let ((x (cons 1 2)))
(setf (cdr x) (list (cdr x)))
x)
您也可以使用rplacd
:
(let ((x (cons 1 2)))
(rplacd x (list (cdr x)))
x)