我没有在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
真的是奇数球吗?!
谢谢!
答案 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)
这就是它的方式。 first
和last
不是一对互补的操作。 last
与rest
和nthcdr
关系更密切。还有butlast
构造了一个新列表,它忽略了给定列表中的最后一项。
first
与last
相比,get
和getf
与set
和setf
无关。