В качестве альтернативы используйте map
:
(let ((l '(1 2 3 4 5 6)))
(map 'list #'list l (cdr l) (cddr l)))
;; ((1 2 3) (2 3 4) (3 4 5) (4 5 6))
Вы можете прочитать его как:
- для списка
l
со значениями (1 2 3 4 5 6)
map
над списком и двумя последовательными cdr
s - путем применения
#'list
к элементам списков map
проходит по параллельному циклу - (останавливается, когда самый короткий список израсходовано)
- и собираем результаты как / в
'list
@ WillNess предложил еще проще:
(let ((l '(1 2 3 4 5 6)))
(mapcar #'list l (cdr l) (cddr l)))
спасибо! Тогда мы можем обобщить, используя только map
вариантов:
(defun subseqs-of-n (l n)
(apply #'mapcar #'list (subseq (maplist #'identity l) 0 n)))
(maplist #'identity l)
эквивалентно (loop for sl on l collect sl)
. Тем не менее,
(loop for sl on l
for i from 0 to n
collect sl)
лучше, потому что он останавливается на n-м цикле цикла ...