使用步长对列表进行切片
Slicing a list with a stepsize
我到处搜索,但没有找到简单的答案。
如何在不求助于 loop
的情况下使用给定的 step
对 Common Lisp 中的列表进行切片?
subseq
不带第三个参数似乎很奇怪,即 (subseq lst start end step)
.
Python相当于:
lst[start:end:step]
标准 CL 中没有类似内容。可以使用 REDUCE
或 DO
来实现它。我只会使用 LOOP
:
辅助函数:
(defun %take (it what)
(cond ((eq what :all) it)
((eq what :none) nil)
((and (numberp what) (plusp what))
(subseq it 0 what))
((and (numberp what) (minusp what))
(last it (- what)))
((and (consp what)
(= (length what) 1)
(numberp (first what)))
(nth (first what) it))
((and (consp what)
(= (length what) 2)
(numberp (first what))
(numberp (second what)))
(let ((end (if (minusp (second what))
(+ (length it) (second what))
(second what))))
(subseq it (first what) end)))
((and (consp what)
(= (length what) 3)
(numberp (first what))
(numberp (second what))
(numberp (third what)))
(let ((start (first what))
(end (if (minusp (second what))
(+ (length it) (second what))
(second what)))
(by-step (third what)))
(loop for e = (subseq it start) then (nthcdr by-step e)
for i from start below end by by-step
collect (first e))))))
TAKE
:
(defun take (thing &rest description)
"Taking things from lists like in Mathematica
Description is one or more of:
:all | :none | [sign]number | ( start [end [step]])"
(cond ((null description) nil)
((and (consp description)
(= (length description) 1))
(%take thing (first description)))
(t (loop for e in (%take thing (first description))
collect (apply #'take e (rest description))))))
示例:
CL-USER 27 > (take '(0 1 2 3 4 5 6 7 8 9 10 11) '(2 7 2))
(2 4 6)
CL-USER 28 > (defun sublist (list start end step)
(take list (list start end step)))
SUBLIST
CL-USER 29 > (sublist '(0 1 2 3 4 5 6 7 8 9 10 11) 2 7 2)
(2 4 6)
我到处搜索,但没有找到简单的答案。
如何在不求助于 loop
的情况下使用给定的 step
对 Common Lisp 中的列表进行切片?
subseq
不带第三个参数似乎很奇怪,即 (subseq lst start end step)
.
Python相当于:
lst[start:end:step]
标准 CL 中没有类似内容。可以使用 REDUCE
或 DO
来实现它。我只会使用 LOOP
:
辅助函数:
(defun %take (it what)
(cond ((eq what :all) it)
((eq what :none) nil)
((and (numberp what) (plusp what))
(subseq it 0 what))
((and (numberp what) (minusp what))
(last it (- what)))
((and (consp what)
(= (length what) 1)
(numberp (first what)))
(nth (first what) it))
((and (consp what)
(= (length what) 2)
(numberp (first what))
(numberp (second what)))
(let ((end (if (minusp (second what))
(+ (length it) (second what))
(second what))))
(subseq it (first what) end)))
((and (consp what)
(= (length what) 3)
(numberp (first what))
(numberp (second what))
(numberp (third what)))
(let ((start (first what))
(end (if (minusp (second what))
(+ (length it) (second what))
(second what)))
(by-step (third what)))
(loop for e = (subseq it start) then (nthcdr by-step e)
for i from start below end by by-step
collect (first e))))))
TAKE
:
(defun take (thing &rest description)
"Taking things from lists like in Mathematica
Description is one or more of:
:all | :none | [sign]number | ( start [end [step]])"
(cond ((null description) nil)
((and (consp description)
(= (length description) 1))
(%take thing (first description)))
(t (loop for e in (%take thing (first description))
collect (apply #'take e (rest description))))))
示例:
CL-USER 27 > (take '(0 1 2 3 4 5 6 7 8 9 10 11) '(2 7 2))
(2 4 6)
CL-USER 28 > (defun sublist (list start end step)
(take list (list start end step)))
SUBLIST
CL-USER 29 > (sublist '(0 1 2 3 4 5 6 7 8 9 10 11) 2 7 2)
(2 4 6)