明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3670|回复: 9

cons与list的区别

[复制链接]
发表于 2018-2-21 23:42:38 | 显示全部楼层 |阅读模式

列表是Lisp的核心数据结构及语法。在Lisp里面,列表的存储方式比较特别,一个列表通常由1个或N个cons来组成的。那个list又与cons是什么关系呢?搞清楚之前,我混乱了许久,读过很多文档及实作才豁然开朗,概要记录一下,看似内容不多,但要理解的东西多了去,整理出来的文字比起之前做的笔记要少多了 :)

关于Cons

cons是一种简单的数据结构,一个cons是由头尾两个元素构成:如下创建一个cons对象:
> (setf x (cons 1 2) )
> x
(1 . 2 )
这创建了一个头是1,尾是2的cons对象。
对cons的操作有两个,car及cdr,分别是读取cons的头和尾元素:
> (car x)
1
> (cdr x)
2

cons的元素可以是任意类型的,当元素也是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,即空列表,所以是可以加进新元素。

说起来简单,实际上要真理解的确是得费点工夫和心思。


发表于 2018-2-22 07:51:07 | 显示全部楼层
在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
发表于 2018-2-22 07:54:16 | 显示全部楼层
其实可以把append以及与lisp的组合一起放在一起,才能更好的理解,我也是一知半解的在用,受教啦,谢谢!
发表于 2018-2-22 22:11:17 | 显示全部楼层
谢谢楼主分享经验!
发表于 2018-2-23 15:11:23 | 显示全部楼层

谢谢楼主分享经验!
发表于 2018-3-3 09:13:07 来自手机 | 显示全部楼层
谢谢楼主的指点
发表于 2019-8-1 19:37:29 | 显示全部楼层
setf是什么函数,自定义的吗
发表于 2020-2-2 12:33:55 | 显示全部楼层
谢谢楼主分享经验!
发表于 2020-6-15 15:35:19 | 显示全部楼层
本帖最后由 e2002 于 2020-6-15 20:33 编辑

换个大家很容易理解的:

AutoLISP 中最重要的数据结构: List ,你可以理解为若干个对象的序列集合(随便什么对象哈,比如:10个人排个队)。

现在在你面前,有个10个同学组成一个队列,这个组成的队列就是一个 list。你可以把这个队列 list 叫做(赋值到变量):Group1:
  1. (setq Group1 (list 0 1 2 3 ...9))
复制代码


这时候你需要把 一个 新同学A 加入这个 Group1,且排在队列的第一个位置(首位):

  1. (setq Group1 (cons A Group1))

做完以后,Group1就变为了 '(A 0 1 2 3 ...9)

如果,还有B ,C,D 等人陆续需要加入,那就不断重复上面的 cons 操作,最后Group1就是:
  1. (D C B A 0 1 2 3 ...9)
复制代码


对于特殊的点对(dot pair), 这个特殊在哪里?现在是两个同学,一个 A ,一个 B ,都是单独的,不在任何一个 List 里面,这时候 (cons A B) ,就把这两个单独的 A ,B 组成了一个点对:

  1. (A . B)
复制代码



那append是干啥呢?其实就是已经有了一些 list ,比如GroupA=(0 1 2),GroupB=(3 4), GroupC=(5 6 7 8 9),
现在需要把这三个变为一整个,那就:
  1. (append GroupA GroupB GroupC) = (0 1 2 3 4 5 6 7 8 9)
复制代码




发表于 2020-9-18 15:50:49 | 显示全部楼层
内存中只有cons,没有list
请看http://bbs.mjtd.com/forum.php?mo ... mp;extra=#pid876955
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-12-20 16:32 , Processed in 0.207123 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表