2016-08-20 110 views
0

我已經遍尋四周,但沒有找到一個簡單的答案。按步驟劃分列表

如何在Common Lisp中對給定的step進行切片,而不是使用loop? 看起來很奇怪,subseq將不會採取第三個參數,即(subseq lst start end step)

的Python相當於:

lst[start:end:step] 

回答

4

沒有什麼標準CL相似。人們可以使用REDUCEDO來實現它。我只想用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)