假设我有一个名为“numbers”的列表(3 1 4 5 2)。我正在寻找一个命令,它将列表从索引0转换为任意索引,即(反向数字2),这将使新列表为(4 1 3 5 2)。
我已经尝试使用谷歌搜索,但找不到合适的功能,而且我在这个阶段自己编写这个功能太过新手了。
谢谢。
答案 0 :(得分:6)
基于libary函数的简单CL版本:
(defun reverse-first-n (list n)
(nreconc (subseq list 0 n) (nthcdr n list)))
答案 1 :(得分:2)
您使用的是Lisp的哪种方言?这是一个Scheme解决方案(使用SRFI 1):
(require srfi/1) ; assuming you're using Racket
(define (reverse-first-n lst n)
(call-with-values (lambda ()
(split-at lst n))
append-reverse!))
我使这个功能真正“反转了前n个元素”,就像你的标题所说,而不像你的问题描述。例如:
> (reverse-first-n '(3 1 4 5 2) 2)
'(1 3 4 5 2)
> (reverse-first-n '(3 1 4 5 2) 3)
'(4 1 3 5 2)
根据OP的要求,这是一个Common Lisp版本。 sds已经发布了一个相当不错的版本,所以我写的版本是我的Scheme解决方案的更直接的端口(append-reverse!
⇒nreconc
; call-with-values
⇒multiple-value-call
;以及我正在将SRFI 1的split-at
移植到CL):
(defun split-at (list n)
(if (zerop n)
(values '() list)
(multiple-value-bind (prefix suffix)
(split-at (cdr list) (1- n))
(values (cons (car list) prefix) suffix))))
(defun reverse-first-n (list n)
(multiple-value-call #'nreconc (split-at list n)))
(为什么split-at
?其目的是同时为take
(subseq
)和drop
(nthcdr
)提供一次输入遍历列表)。