Список, который выглядит как (1 2 3)
Я построил как (1 . (2 . (3 . ())))
или, если вы более знакомы с cons
(cons 1 (cons 2 (cons 3 '())))
. Таким образом (list 1 2 3))
делает именно это под капотом. Это важная информация для того, чтобы уметь работать с ними. Обратите внимание, что первый cons
не может быть применен до завершения (cons 2 (cons 3 '()))
, поэтому список всегда создается от конца к началу. Также список повторяется от начала до конца.
Итак, вы хотите:
(define lst '(1 2 3 4 5))
(n-first lst 0) ; == '()
(n-first lst 1) ; == (cons (car lst) (n-first (- 1 1) (cdr lst)))
(n-first lst 2) ; == (cons (car lst) (n-first (- 2 1) (cdr lst)))
append
работает так:
(define (append lst1 lst2)
(if (null? lst1)
lst2
(cons (car lst1)
(append (cdr lst1) lst2))))
append
- это O (n) сложность времени, поэтому если вы используете эту каждую итерацию из n
частей списка, вы получите O (n ^ 2). Для небольших списков вы этого не заметите, но даже списки среднего размера из ста тысяч элементов, которые вы заметите, append
использует примерно в 50 раз больше времени, чем один cons
, а для больших списков вы не хотите дождитесь результата, так как он растет в геометрической прогрессии.