5.3 访问列表元素

Function: car cons-cell

该函数返回 cons 单元 cons-cell 第一个槽位所引用的值。换句话说,它返回 cons-cellCAR

作为特例,若 cons-cellnil,该函数返回 nil。因此,任何列表都是合法参数。若参数既非 cons 单元也非 nil,则会触发错误。

(car '(a b c))
     ⇒ a
(car '())
     ⇒ nil
Function: cdr cons-cell

该函数返回 cons 单元 cons-cell 第二个槽位所引用的值。换句话说,它返回 cons-cellCDR

作为特例,若 cons-cellnil,该函数返回 nil;因此,任何列表都是合法参数。若参数既非 cons 单元也非 nil,则会触发错误。

(cdr '(a b c))
     ⇒ (b c)
(cdr '())
     ⇒ nil
Function: car-safe object

该函数允许你获取 cons 单元的 CAR 值,同时避免因传入其他数据类型而触发错误。若 object 是 cons 单元,则返回其 CAR 值;否则返回 nil。这与 car 函数形成对比,car 函数在 object 非列表时会触发错误。

(car-safe object)
≡
(let ((x object))
  (if (consp x)
      (car x)
    nil))
Function: cdr-safe object

该函数允许你获取 cons 单元的 CDR 值,同时避免因传入其他数据类型而触发错误。若 object 是 cons 单元,则返回其 CDR 值;否则返回 nil。这与 cdr 函数形成对比,cdr 函数在 object 非列表时会触发错误。

(cdr-safe object)
≡
(let ((x object))
  (if (consp x)
      (cdr x)
    nil))
Macro: pop listname

该宏提供了一种便捷方式,可一次性查看列表的 CAR 元素并将其从列表中移除。它作用于存储在 listname 中的列表。该宏会移除列表首个元素,将 CDR 部分保存回 listname,然后返回被移除的元素。

在最简单的情况下,listname 是一个未加引号、指代列表的符号;此时该宏等价于 (prog1 (car listname) (setq listname (cdr listname)))

x
     ⇒ (a b c)
(pop x)
     ⇒ a
x
     ⇒ (b c)

更通用的情况是,listname 可以是广义变量(Generalized Variable)。此时该宏会通过 setf 将值保存到 listname 中。See 广义变量

关于向列表中添加元素的 push 宏,see 修改列表变量

Function: nth n list

该函数返回列表 list 的第 n 个元素。元素编号从 0 开始,因此列表的 CAR 是第 0 号元素。若 list 长度小于等于 n,则返回 nil

(nth 2 '(1 2 3 4))
     ⇒ 3
(nth 10 '(1 2 3 4))
     ⇒ nil

(nth n x) ≡ (car (nthcdr n x))

函数 elt 与之类似,但适用于任意类型的序列。出于历史原因,其参数顺序与 nth 相反。See 序列

Function: nthcdr n list

该函数返回列表 list 的第 nCDR。换句话说,它跳过 list 的前 n 个链接,返回剩余部分。

n 为 0,nthcdr 返回整个 list;若 list 长度小于等于 nnthcdr 返回 nil

nthcdr 的别名是 drop

(nthcdr 1 '(1 2 3 4))
     ⇒ (2 3 4)
(nthcdr 10 '(1 2 3 4))
     ⇒ nil
(nthcdr 0 '(1 2 3 4))
     ⇒ (1 2 3 4)
Function: take n list

该函数返回列表 list 的前 n 个元素。本质上,它返回 nthcdr 函数会跳过的那部分 list 内容。

若列表长度小于 ntake 返回原列表 list;若 n 为 0 或负数,take 返回 nil

通常,(append (take n list) (drop n list)) 会返回一个与原列表 list 完全相等的列表。

(take 3 '(a b c d))
     ⇒ (a b c)
(take 10 '(a b c d))
     ⇒ (a b c d)
(take 0 '(a b c d))
     ⇒ nil
Function: ntake n list

这是 take 的 “破坏性” 版本,通过修改参数的列表结构实现功能。这使其速度更快,但列表 list 的原始值可能丢失。

若列表长度小于 nntake 原样返回列表 list;若 n 为 0 或负数,ntake 返回 nil;否则返回截断为前 n 个元素的列表 list

这意味着,除非确定 n 为正数,否则通常应使用其返回值,而非仅依赖截断效果。

Function: last list &optional n

该函数返回列表 list 的最后一个链接(link),该链接的 car 即为列表的最后一个元素。若 list 为空(null),返回 nil。若 n 非-nil,则返回倒数第 n 个链接;若 n 大于列表 list 长度,则返回整个列表 list

Function: safe-length list

该函数返回列表 list 的长度,且无触发错误或无限循环的风险。它通常返回列表中不同 cons 单元的数量;但对于循环列表,返回值仅为上限(往往偏大)。

list 既非 nil 也非 cons 单元,safe-length 返回 0。

当无需担心列表是循环列表时,计算列表长度最常用的方式是使用 length 函数。See 序列

Function: caar cons-cell

等价于 (car (car cons-cell))

Function: cadr cons-cell

等价于 (car (cdr cons-cell))(nth 1 cons-cell)

Function: cdar cons-cell

等价于 (cdr (car cons-cell))

Function: cddr cons-cell

等价于 (cdr (cdr cons-cell))(nthcdr 2 cons-cell)

除上述函数外,还定义了 24 个由 carcdr 组合而成的函数,命名形式为 cxxxrcxxxxr(每个 xad)。其中 cadrcaddrcadddr 分别用于取出列表的第二个、第三个、第四个元素。 cl-lib 库也提供了对应的函数,命名为 cl-secondcl-thirdcl-fourth。 See List Functions in Common Lisp Extensions

Function: butlast x &optional n

该函数返回移除了最后一个(或最后 n 个)元素的列表 x。若 n 大于 0,函数会复制列表以避免破坏原列表。 通常,(append (butlast x n) (last x n)) 会返回与原列表 x 相等的列表。

Function: nbutlast x &optional n

这是 butlast 的 “破坏性” 版本,通过修改对应元素的 cdr 实现功能,而非复制列表。


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike