跳转到内容

Common Lisp/基础主题/列表

来自维基教科书,开放的书籍,开放的世界
本模块尚未完成。欢迎改进。

列表在 Common Lisp 中由称为cons 单元的配对构成。每个单元有两个部分,历史上称为 car(第一部分)和 cdr(其余部分)。

(car . cdr)

列表通过让第一个单元的 cdr 指向另一个 cons 单元来使用 cons 单元实现。

空列表也称为 nil,它的书面表示形式是 nil 本身或空列表:()。

您可以使用 cons 创建一个列表,以构造一个具有左右部分的新 cons 单元。

  (cons 'a '())                      (A)
  (cons 'a '(b))                     (A B)
  (cons 'a (cons 'b (cons 'c nil)))  (A B C)

请记住,可以创建不是列表的 cons 单元。

  (cons 'a 'b)  (A . B)

这被称为点分列表。为了成为一个正确的列表,cons 单元链中的最后一个 cdr 必须指向空列表 (nil)。您也可以使用函数list创建列表

  (list 'a 'b 'c)    (A B C)

等效于

  (cons 'a (cons 'b (cons 'c '())))  (A B C)
  (cons 'a (cons 'b (cons 'c nil)))  (A B C)
  (cons 'a '(b c))                   (A B C)
  '(a b c)                           (A B C)

您可以使用函数car(或first)和cdr(或rest)访问列表的成员。

  (setf list '(a b c))
  (car list)     a
  (first list)   a

  (cdr list)     (b c)
  (rest list)    (b c)

Common Lisp 还定义了函数secondthirdfourth(一直到tenth)。请注意,secondcdrrest不同。cdrrest都返回第一个元素之后的剩余列表,而second返回列表中的第二个元素。

  (rest list)    (b c)
  (second list)  b
  (third list)   c
  (fourth list)  nil

列表是序列,因此对序列进行操作的函数也对列表进行操作。

  (subseq list 0 1)   (a)
  (subseq list 0 2)   (a b)

函数nth还允许您从列表中检索选定的元素。

  (nth 0 list)   a

请注意,列表中的第一个元素是第 0 个。Common Lisp 还有几种用于操作列表内容的形式(函数和宏)。mapcar 可用于一次处理列表中的每个元素,以构建新的列表。

  (defun add2 (n)
    (+ 2 n))
  (mapcar #'add2 '(1 2 3))   (3 4 5)

在该示例中,我们正在对单个列表进行映射,因此我们使用了一元函数(一个参数的函数)。该#'是将函数作为参数传递给函数的一种特殊方式。我们将在下一章中详细讨论它。也可以对多个列表进行映射 - 函数必须与列表的数量具有相同的参数个数。

  (mapcar #'+ '(1 2 3) '(4 5 6))  (5 7 9)
华夏公益教科书