cons与list的区别
列表是Lisp的核心数据结构及语法。在Lisp里面,列表的存储方式比较特别,一个列表通常由1个或N个cons来组成的。那个list又与cons是什么关系呢?搞清楚之前,我混乱了许久,读过很多文档及实作才豁然开朗,概要记录一下,看似内容不多,但要理解的东西多了去,整理出来的文字比起之前做的笔记要少多了 :)关于Conscons是一种简单的数据结构,一个cons是由头尾两个元素构成:如下创建一个cons对象:> (setf x (cons 1 2) )
> x
(1 . 2 )
这创建了一个头是1,尾是2的cons对象。
对cons的操作有两个,car及cdr,分别是读取cons的头和尾元素:
> (car x)
1
> (cdr x)
2cons的元素可以是任意类型的,当元素也是cons时:
> (setf y (cons 1 (cons 2 (cons 3 4))))
> y
(1 2 3 . 4)
y值可以这样理解:它由三个(点之前的元素个数)cons组成,最后一个元素是4
> (car y)
1
> (cdr y)
(2 3 . 4)Cons与List我们再来创建一个特别的cons:
> (setf z (cons 1 (cons 2 (cons 3 (cons 4 nil)))))
> z
(1 2 3 4)
z值可以这样理解:它由4个cons组成,最后一个元素是nil
z也等价于:
> (list 1 2 3 4)1、像y这样的列表,我们称之为点列表,其特征是cons的最后元素是一个原子,非nil,非空列表。
2、而像z这样的列表,我们称之为真列表(list) ,其特重是cons的最后元素是nil,即空列表。真列表打印输出时,会隐藏掉最后的nil值及点。
3、所以,list是一种特殊的cons,即真列表是一种特殊的点列表。
4、真列表(list)是可以使用append函数的,而点列表不行:
> (append z 5)
(1 2 3 4 5)
> (append y 5)
*** Eval error ***Wrong type argument: listp, 4
错误指出,4(y中的最后一个元素) 不是一个list,所以不能append。
真列表(list) 最后的元素是nil,即空列表,所以是可以加进新元素。说起来简单,实际上要真理解的确是得费点工夫和心思。
在Visual LISP中 (append z 5)根本行不通
_$ (setq z (cons 1 (cons 2 (cons 3 (cons 4 nil)))))
(1 2 3 4)
_$(append z 5)
; 错误: 参数类型错误: listp 5 其实可以把append以及与lisp的组合一起放在一起,才能更好的理解,我也是一知半解的在用,受教啦,谢谢! 谢谢楼主分享经验!
谢谢楼主分享经验! 谢谢楼主的指点 setf是什么函数,自定义的吗 谢谢楼主分享经验! 本帖最后由 e2002 于 2020-6-15 20:33 编辑
换个大家很容易理解的:
AutoLISP 中最重要的数据结构: List ,你可以理解为若干个对象的序列集合(随便什么对象哈,比如:10个人排个队)。
现在在你面前,有个10个同学组成一个队列,这个组成的队列就是一个 list。你可以把这个队列 list 叫做(赋值到变量):Group1:
(setq Group1 (list 0 1 2 3 ...9))
这时候你需要把 一个 新同学A 加入这个 Group1,且排在队列的第一个位置(首位):
(setq Group1 (cons A Group1))
做完以后,Group1就变为了 '(A 0 1 2 3 ...9)
如果,还有B ,C,D 等人陆续需要加入,那就不断重复上面的 cons 操作,最后Group1就是:
(D C B A 0 1 2 3 ...9)
对于特殊的点对(dot pair), 这个特殊在哪里?现在是两个同学,一个 A ,一个 B ,都是单独的,不在任何一个 List 里面,这时候 (cons A B) ,就把这两个单独的 A ,B 组成了一个点对:
(A . B)
那append是干啥呢?其实就是已经有了一些 list ,比如GroupA=(0 1 2),GroupB=(3 4), GroupC=(5 6 7 8 9),
现在需要把这三个变为一整个,那就:
(append GroupA GroupB GroupC) = (0 1 2 3 4 5 6 7 8 9)
内存中只有cons,没有list
请看http://bbs.mjtd.com/forum.php?mod=viewthread&tid=182323&page=1&extra=#pid876955
页:
[1]