List 返回不包含最后一个元素的列表

List 返回不包含最后一个元素的列表,list,functional-programming,scheme,lisp,racket,List,Functional Programming,Scheme,Lisp,Racket,我刚开始学球拍 我有以下代码: #lang racket (define l1 '(1 2 3 4)) (car l1) (cdr l1) (汽车l1)返回1。 (cdr l1)返回“(2 3 4) 是否有返回'(1 2 3)的函数 我试过这个: #lang racket (define l1 '(1 2 3 4)) (map (lambda (l i) (if (not (= i (sub1 (length l1)))) l '())) l1 (range 0 (length

我刚开始学球拍

我有以下代码:

#lang racket

(define l1 '(1 2 3 4))
(car l1)
(cdr l1)
(汽车l1)
返回1。
(cdr l1)
返回“(2 3 4)

是否有返回
'(1 2 3)
的函数

我试过这个:

#lang racket

(define l1 '(1 2 3 4))
(map
 (lambda (l i)
   (if (not (= i (sub1 (length l1)))) l '()))
 l1 (range 0 (length l1)))
但是,它返回:
”(123())

我也尝试过:

#lang racket

(define l1 '(1 2 3 4))
(map
 (lambda (l i)
   (cond ((not (= i (sub1 (length l1)))) l )))
 l1 (range 0 (length l1)))

但是,它返回:
”(1233)
像这样的东西怎么样

(define (myCdr l)
    (if (not (pair? (cdr l)))
        '()
        (cons (car l) (myCdr (cdr l)))
    )
)

像这样的怎么样

(define (myCdr l)
    (if (not (pair? (cdr l)))
        '()
        (cons (car l) (myCdr (cdr l)))
    )
)

map
函数始终返回与其输入长度相同的列表。您需要一个比输入短的输出列表。您要查找的函数传统上称为
,但最后一个是

(define (but-last xs) (reverse (cdr (reverse xs))))

map
函数始终返回与其输入长度相同的列表。您需要一个比输入短的输出列表。您要查找的函数传统上称为
,但最后一个是

(define (but-last xs) (reverse (cdr (reverse xs))))

length
通常是Scheme中的反模式,因为需要读取整个列表才能得到结果。W.Ness指出,
map
不会改变列表的结构,
filter
的行为基于列表的值,两者都不适合您的需要

您可以使用直接递归计算列表的
init
,而不是首先进行可能昂贵的计算或笨拙地应用库函数-

(define (init l)
  (cond ((null? l)
         (error 'init "cannot get init of empty list"))
        ((null? (cdr l))
         null)
        (else
         (cons (car l)
               (init (cdr l))))))

(init '(a b c d e)) ;; '(a b c d)
(init '(a))         ;; '(a)
(init '())          ;; init: cannot get init of empty list
或者只使用一个
反向
-

(define (init l)
  (let loop ((acc null)
             (l l))
    (cond ((null? l)
           (error 'init "cannot get init of empty list"))
          ((null? (cdr l))
           (reverse acc))
          (else
           (loop (cons (car l) acc)
                 (cdr l))))))

(init '(a b c d e)) ;; '(a b c d)
(init '(a))         ;; '(a)
(init '())          ;; init: cannot get init of empty list
最后是一个尾部递归形式,它不使用
length
reverse
。有关如何工作的更多直观信息,请参阅-


length
通常是Scheme中的反模式,因为需要读取整个列表才能得到结果。W.Ness指出,
map
不会改变列表的结构,
filter
的行为基于列表的值,两者都不适合您的需要

您可以使用直接递归计算列表的
init
,而不是首先进行可能昂贵的计算或笨拙地应用库函数-

(define (init l)
  (cond ((null? l)
         (error 'init "cannot get init of empty list"))
        ((null? (cdr l))
         null)
        (else
         (cons (car l)
               (init (cdr l))))))

(init '(a b c d e)) ;; '(a b c d)
(init '(a))         ;; '(a)
(init '())          ;; init: cannot get init of empty list
或者只使用一个
反向
-

(define (init l)
  (let loop ((acc null)
             (l l))
    (cond ((null? l)
           (error 'init "cannot get init of empty list"))
          ((null? (cdr l))
           (reverse acc))
          (else
           (loop (cons (car l) acc)
                 (cdr l))))))

(init '(a b c d e)) ;; '(a b c d)
(init '(a))         ;; '(a)
(init '())          ;; init: cannot get init of empty list
最后是一个尾部递归形式,它不使用
length
reverse
。有关如何工作的更多直观信息,请参阅-


这里还有另一种选择,假设列表不是空的。它是高效的(它只对列表执行一次遍历),而且没有比这更简单的了

(define (delete-last lst)
  (drop-right lst 1))

(delete-last '(1 2 3 4))
=> '(1 2 3)

这里还有另一种选择,假设列表不是空的。它是高效的(它只对列表执行一次遍历),而且没有比这更简单的了

(define (delete-last lst)
  (drop-right lst 1))

(delete-last '(1 2 3 4))
=> '(1 2 3)

我自己使用递归的解决方案:

#lang racket

(define but-last
  (lambda (l)
    (cond ((null? (cdr l)) '())
          (else (cons (car l) (but-last (cdr l)))))))
另一种解决方案是使用
过滤器not
map

#lang racket

(define l1 '(1 2 3 4))

(filter-not empty? (map
 (lambda (l i)
   (if (not (= i (sub1 (length l1)))) l empty))
 l1 (range 0 (length l1))))

我自己使用递归的解决方案:

#lang racket

(define but-last
  (lambda (l)
    (cond ((null? (cdr l)) '())
          (else (cons (car l) (but-last (cdr l)))))))
另一种解决方案是使用
过滤器not
map

#lang racket

(define l1 '(1 2 3 4))

(filter-not empty? (map
 (lambda (l i)
   (if (not (= i (sub1 (length l1)))) l empty))
 l1 (range 0 (length l1))))

这里还有一个,通过拉链:

#lang racket

(require srfi/1)

(define (but-last-zip xs)
  (if (null xs)
      xs                      ; or error, you choose
      (map (lambda (x y) x)
           xs
           (cdr xs))))
下面是另一个,通过添加列表模拟过滤,其中空列表会自行消失:

(define (but-last-app xs)
  (if (null? xs)
      xs
      (let ((n (length xs)))
        (apply append                  ; the magic
               (map (lambda (x i)
                      (if (= i (- n 1)) '() (list x)))
                    xs
                    (range n))))))
或者我们可以直接使用装饰-过滤器-取消装饰,这甚至是更多的代码

(define (but-last-fil xs)
  (if (null? xs)
      xs
      (let ((n (length xs)))
        (map car
             (filter (lambda (x) (not (null? x)))
                     (map (lambda (x i)
                            (if (= i (- n 1)) '() (list x)))
                          xs
                          (range n)))))))

这里还有一个,通过拉链:

#lang racket

(require srfi/1)

(define (but-last-zip xs)
  (if (null xs)
      xs                      ; or error, you choose
      (map (lambda (x y) x)
           xs
           (cdr xs))))
下面是另一个,通过添加列表模拟过滤,其中空列表会自行消失:

(define (but-last-app xs)
  (if (null? xs)
      xs
      (let ((n (length xs)))
        (apply append                  ; the magic
               (map (lambda (x i)
                      (if (= i (- n 1)) '() (list x)))
                    xs
                    (range n))))))
或者我们可以直接使用装饰-过滤器-取消装饰,这甚至是更多的代码

(define (but-last-fil xs)
  (if (null? xs)
      xs
      (let ((n (length xs)))
        (map car
             (filter (lambda (x) (not (null? x)))
                     (map (lambda (x i)
                            (if (= i (- n 1)) '() (list x)))
                          xs
                          (range n)))))))
这里有一个等价物,它不依赖Racket中的
srfi/1
:没有
srfi/1
Racket的
map
坚持其所有参数都是相同的长度(与实际版本一样),但在其他LISP中,函数通常在最短列表的末尾终止

此函数使用Racket的
表示/list
,并假设空列表的结果为空列表

#lang racket

(define (but-last-zip xs)
  (for/list ([x xs] [y (if (null? xs) xs (rest xs))])
    x))
我认为Will的版本更纯粹:我认为将函数映射到事物上是一件非常Lisp的事情,而
for/list
对我来说感觉不那么Lisp。这个版本的唯一优点是它不需要模块。

这里有一个等价物,它不依赖Racket中的
srfi/1
:没有
srfi/1
Racket的
map
坚持它的所有参数都是相同的长度(事实上这个版本也是如此)但在其他Lisp中,函数通常在最短列表的末尾终止

此函数使用Racket的
表示/list
,并假设空列表的结果为空列表

#lang racket

(define (but-last-zip xs)
  (for/list ([x xs] [y (if (null? xs) xs (rest xs))])
    x))

我认为Will的版本更纯粹:我认为将函数映射到事物上是一件非常Lisp的事情,而
for/list
对我来说感觉不那么Lisp。这个版本的唯一优点是它不需要模块。

您可以使用
反向
?@WillNess是的,我想可以。但我想让它可以移植到Scheme(如果可能的话)。试试看。:)你能用它得到相反的“butlast”元素吗?(这就是您想要的函数在common lisp中的名称,顺便说一句——“butlast”)。我正在尝试这样做
(filter not empty?(map(lambda(l I))…
,但它不起作用。而且,我正在尝试使用递归而不使用
map
。但是如果你刚刚开始学习Lisp,那么自己用直接递归编码是一个很好的练习,也就是用just-if、null?cons、car、cdr和递归来感受它。你应该首先喜欢编写这样的小函数是的,我想是的。但是我想让它可以移植到Scheme(如果可能的话)。试试看。:)你能用它得到反向的“butlast”元素吗?(这就是您想要的函数在common lisp中的名称,顺便说一句——“butlast”)。我正在尝试这样做
(filter not empty?(map(lambda(l I)…)。。。