Common Lisp:first先返回,但是last返回最后一个列表 - 呵呵?

时间:2013-07-18 18:53:47

标签: lisp common-lisp

我没有在Common-Lisp中获得第一个/最后一个。是的,我知道它是如何工作的,但我不知道为什么它会这样运作。

基本上,要获取列表中的第一项,我可以使用(first mylist)。但是,如果我想要最后一项,(last mylist)不会给我这个;相反,它给了我一个包含我列表中最后一项的列表!

(我正在使用Clozure-CL,它有一些其他奇怪的东西对我来说似乎是错误的,但是,因为我是一个Lisp-n00b,我试图不要因为旧版本而失败“解释器被破坏了!“技巧:))

所以,例如:

? (setq x '((1 2) (a b)))
=> ((1 2) (A B))

? (first x)
=> (1 2)  ; as expected

? (last x)
=> ((A B))  ; why a list with my answer in it?!

? (first (last x))
=> '(A B)  ; This is the answer I'd expect from plain-old (last x)

有人可以帮我理解为什么最后这样做吗?我错误地使用这些物品了吗? first真的是奇数球吗?!

谢谢!

4 个答案:

答案 0 :(得分:8)

在Common Lisp last应该从documentation返回一个列表:

last list &optional n => tail
list---a list, which might be a dotted list but must not be a circular list.
n---a non-negative integer. The default is 1.
tail---an object. 
  

last返回列表的最后n个conses(不是最后n个元素)。如果list是(),则last返回()。

例如:

(setq x (list 'a 'b 'c 'd))
(last x) =>  (d)

是的,这是违反直觉的。在Lisp的其他版本中,它的名字可以解释,例如在Racket(Scheme方言)中:

(define x '((1 2) (a b)))
(first x) => '(1 2)
(last x) => '(a b)

(define x (list 'a 'b 'c 'd))
(last x) =>  'd

答案 1 :(得分:7)

除了访问最后一个元素外,返回最后一个元素并不是很有用;返回最后一个缺点让你做这样的事情:

(let ((x (list 1 2 3)))
  (setf (cdr (last x)) '(4))
  x)

=> '(1 2 3 4)

虽然您仍可以(car (last x))访问最后一个元素。

答案 2 :(得分:4)

Common Lisp的错误名称函数last为您提供最后的缺点

它应该被称为tail,因为有一个函数tailp,但我的猜测是这个名字因历史/兼容性原因而停滞不前。

通常,它会在列表末尾之前为您提供列表的 nth 尾部或 nth 缺点。

答案 3 :(得分:4)

这就是它的方式。 firstlast不是一对互补的操作。 lastrestnthcdr关系更密切。还有butlast构造了一个新列表,它忽略了给定列表中的最后一项。

firstlast相比,getgetfsetsetf无关。