Нарезка списка с размером шага

lisp common-lisp

97 просмотра

1 ответ

Я искал все вокруг, но не нашел простого ответа.

Как я могу нарезать список в Common Lisp с данным, stepне прибегая к loop? Кажется странным , что subseqне будет принимать третий параметр, то есть (subseq lst start end step).

Эквивалент Python:

 lst[start:end:step]
Автор: dangom Источник Размещён: 08.11.2019 11:26

Ответы (1)


4 плюса

Решение

Ничего подобного в стандартном 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)
Автор: Rainer Joswig Размещён: 20.08.2016 04:33
Вопросы из категории :
32x32