终于开始讨论列表了,列表是Lisp的精华之一,也是学习Lisp的难点之一。

列表的精彩之处在于,它不仅仅是Lisp中的一种数据结构,它也是Lisp语言的构成部分,Lisp语言中的所有语句都是一个列表。
反观我们常见的编程语言,语言中的语句有特定的语法,而这些语法只有编译器可以理解,用编程语言自己去解释自己几乎就成了一个不可能完成的任务。
举个例子,看看下面的java语句:

int i = j + 10 ;

这句代码给java编译器去解释是很简单的,i的值会等于j加10.
不过,如果给你下面名叫myString这个字符串:

String myString = "int i = j + 10 ;"

你能否通过java代码解析myString,并准确理解这行代码的意义?
对于一般程序员来讲这个任务几乎是不可能完成的。当然,对于大牛来讲是可以的,不过是用java语言写一个java编译器而已。

而Lisp程序员就幸运多了,不用成为大牛也可以通过Lisp语言解析Lisp语句,因为Lisp语句本身就是一个列表,如下面的代码:

(setf i (+ j 10))

以上语句就是一个列表,通过Lisp语言的列表操作函数可以轻易地解析出其中的所有元素。当然,单纯地解析语句还不能算是一个编译器,要做一个Lisp编译器还需要很多工作。

更为幸运的是,Lisp语言中提供了eval函数,把一个列表当参数传递给eval函数,eval函数会解析并运行该参数,就像是在Lisp语言中提供了一个现成的Lisp编译器。
就像下面的代码:

(defun eval-test ()(setf j 5)(eval '(setf i (+ j 10)))(format *query-io* "i is: ~A ~%" i))

其中(setf i (+ j 10))被轻松地编译执行了。
在这里编译期和运行期的界限被模糊了,我们有时会分不清我们是在写程序还是在编译程序。这也就是为什么Lisp被称之为“可以编写语言的语言”。

有关“可以编写语言的语言”,更多的内容我们在讨论宏(macro)的时候深入讨论,在这里只是开始讨论列表而已。

如果我们在学习Lisp中的列表时把列表当作一个单纯的数据结构会比较简单一些,所以我们就先从数据结构的角度先了解一下列表。
其实,就是把列表当作一个简单的数据结构,我们也无法在一篇文章中完全介绍它,所以我们分几篇文章来讨论列表。

因为常规语言中没有对应的数据结构,我们首先需要解释一下什么是Lisp语言中列表。
Lisp语言中的列表可以简单地理解为圆括号包围的一堆数据,数据之间用空格隔开,像下面这个就是一个列表:

(a b c)

以上列表包含三个元素,分别是a ,b  和c。
下面还有一个列表的样例:

(abc 10 efg hi)

以上列表包含四个元素,分别是abc, 10 , efg和hi。
列表中单个的元素被称作原子(atom)

列表的元素不一定需要是原子,可以是另一个列表,如下面这样:

(a b (abc 10 efg hi) c)

以上列表有四个元素,分别是a , b  , (abc 10 efg hi)和 c。

如果我们希望创建一个列表,赋予变量my-list,下面这样是不行的:

(setf my-list (a b c))

原因是Lisp语言解释器把(a b c)当作一行语句,尝试运算它,运算时会把a当作函数名,而b和c当作是参数。

正确的写法应该是:

(setf my-list '(a b c))

其中的'符号表示后面的列表不需要进行计算。

另外一种写法是:

(setf my-list (quote (a b c)))

第一中写法中的'(a b c)其实就是(quote (a b c))的简写。

再还有一种写法是:

(setf my-list (list 'a 'b 'c))

其中list函数用于创建列表,将元素'a, 'b 和'c组合成一个列表。
以上三个语句可以认为是等价的。

创建了列表就需要访问它,常规的访问某个位置的函数是nth,形式如下:

(nth 0 my-list)

以上函数返回my-list中的第一个元素,可以发现nth函数同样是以0为下标起始点的,也就是说下面的函数会返回my-list的第8个元素:

(nth 7 my-list)

如果希望对列表进行遍历,可以使用loop函数,形式如下:

         (loop for x in my-list do(format *query-io* "~a::" x))

以上函数对my-list进行遍历,逐个输出元素的值。

此外,因为列表的特殊性,Lisp语言还提供了car和cdr两个函数对列表进行操作。
car函数返回列表的第一个元素,如:

(car my-list)

以上函数返回my-list中的第一个元素,以原子的方式返回。
结合上面的定义,(car my-list)的返回值是A.

而cdr函数返回列表第一个元素以后的所有元素,返回时是一个列表。如下面的函数:

(cdr my-list)

结合以上的定义,该函数返回(B C)

更为有趣的是cdr函数中的d字符可以重复,如cddr,或者是cdddr。
其中cddr返回第二个元素以后的所有元素,而cdddr返回第三个元素以后的所有元素。d的重复次数最多为四次,cddddr这样是合法的,而cdddddr会报错。

Lisp中还可以通过(cadr my-list)这样的形式表示(car (cdr my-list))
这样返回的是my-list中第二个元素,以原子的形式返回。
同样,其中的d字符可以,最多重复三次,如caddr, cadddr这样。

如果希望往一个列表添加元素,可以使用append函数,形式如下:

(append my-list '(d))

结合上面对my-list的定义,my-list的值是(A B C),所以以上函数返回(A B C D)

注意函数(append my-list '(d))并不会改变列表my-list的值,它只是返回了一个新的列表,新的列表中包含了my-list中的值和新添加的值。

如果希望操作my-list,让my-list多一个元素D,需要将代码写成这样:

(setf my-list (append my-list '(d)))

以上就是lisp中列表的一些基本操作。
不过列表的操作远不止这些,更多的列表操作我们在以后的文章中讨论。

Lisp语言:列表(List)相关推荐

  1. 你不可不知的9种Lisp语言思想

    本文来源 Lisp语言诞生的时候就包含了9种新思想.其中一些我们今天已经习以为常,另一些则刚刚在其他高级语言中出现,至今还有2种是Lisp独有的.按照被大众接受的程度,这9种思想依次如下排列. (1) ...

  2. Common Lisp语言快速入门

    zhezhelin Common Lisp语言快速入门 Lisp是软件领域的分裂力量.一方面,Lisp爱好者誓言Lisp比软件领域内的其它语言都更加快捷.整洁和强大:而反对者则辩称,不可靠的执行和库支 ...

  3. lisp语言是最好的语言_Lisp可能不是数据科学的最佳语言,但是我们仍然可以从中学到什么呢?...

    lisp语言是最好的语言 This article is in response to Emmet Boudreau's article 'Should We be Using Lisp for Da ...

  4. (转)为什么LISP语言如此先进?

    很高兴今天又读到了一篇非常有启发性的文章.说实话,读完后虽然有些部分还是觉得有点模糊,但这种模糊里还是有一点感觉.哈哈,先不说这些玄乎的话了.在我看来,是应该学习LISP的,感觉这门语言被推向了神坛, ...

  5. 为什么Lisp语言如此先进?(译文)

    上周,<黑客与画家>总算翻译完成,已经交给出版社了. 翻译完这本书,累得像生了一场大病.把书稿交出去的时候,心里空荡荡的,也不知道自己得到了什么,失去了什么. 希望这个中译本和我的努力,能 ...

  6. Lisp语言:循环控制

    了解了Lisp语言的条件判断,让我们看看Lisp语言的循环控制.对于稍有编程经验的人来说,循环是比较容易理解的,一般语言里面的循环无外乎for循环,while循环,do until循环等,有些语言的循 ...

  7. Emacs Lisp语言

    An Introduction to Programming in Emacs Lisp 这本书 emacs 里有,按"C-h i",输入"m,Emacs Lisp In ...

  8. lisp语言(转自百度)

    lisp语言 Lisp 语言最早是在 20 世纪 50 年代末由麻省理工学院(MIT)为研究人工智能而开发的.Lisp 语言的强大使它在其它方面诸如编写编辑命令和集成环境等显示其优势.而 GNU Em ...

  9. 用lisp语言写一段cad提取坐标代码

    好的,这是用 Lisp 语言写的一段 CAD 提取坐标的代码.这段代码假设已经有了一个名为 "points" 的列表,其中包含了若干个点的坐标(x, y): (defun extr ...

最新文章

  1. linux系统下一个冷门的RAID卡ioc0及其监控mpt-status
  2. C语言scanf函数的返回值、scanf函数的安全版、在while条件中使用scanf函数
  3. xml配置linux启动脚本,linux中利用Shell脚本实现自动安装部署weblogic服务
  4. 聚类(中)层次聚类 基于密度的聚类算法
  5. 王哲:Cocos2d-x 3.0引擎带来了什么?
  6. 删除kafka topic
  7. JSON jquery 与php 入门
  8. linux系统管理命令使用,Linux系统管理命令使用说明
  9. 360安全卫士v3.0beta3版发布!
  10. 8086汇编语言实现数组冒泡排序(全注释)
  11. Oracle 自动诊断信息库(Automatic Diagnostic Repository,ADR)
  12. 柔性穿刺针有限元模型
  13. Sublime Text安装与配置教程
  14. Android中如何Hook住JNI方法
  15. erdas几何校正_遥感图像的几何校正
  16. nginx下的一级域名跳转到二级域名的配置
  17. LabVIEW采集鼠标、键盘数据
  18. 南阳OJ题目33---蛇形填数
  19. 自动化办公-excel篇 openpyxl的使用详解
  20. 网址中为什么会有好多%BE%B2%D0%之类的--URLEncode

热门文章

  1. Sql Server 2008卸载后再次安装一直报错
  2. GO学习笔记:struct的匿名字段
  3. altera DCFIFO IP核 功能仿真
  4. sumproduct 公式
  5. 伪装学渣未删减部分_深圳妈妈分享!如何在2年内把“学渣”儿子送进世界百强名校!...
  6. uboot启动过程教程详解
  7. SDH原理--3.开销和指针
  8. GOM引擎传奇中增加会员时间的脚本教程分享
  9. windows 异步IO操作的几种实现方法
  10. 数据库多表查询优化思路之笛卡儿积