如何在Scheme中创建连续数字列表?
在Python中创建1到10的整数列表将是range(1,11)
。方案有等价物吗?
mzscheme --version
提供Welcome to Racket v5.2.1.
修改:按https://stackoverflow.com/a/7144310/596361实现范围功能,需要此代码:
#lang racket
(require srfi/1)
(iota 5 1)
答案 0 :(得分:10)
寻找 iota (如SRFI-1中所定义)。
示例:(iota 10 1)从1开始给出10个连续的整数(而不是默认值0)。
iota 不会使用与范围相同的参数,但它会复制所有功能 - 升序范围,降序范围,如果只给出一个边界,则从0开始,指定间隔的能力。 / p>
答案 1 :(得分:5)
如果第一个数字较低则为升序范围,如果较高则为降序范围:
(define range
(lambda (n m)
(cond
((= n m) (list n))
(else (cons n (range ((if (< n m) + -) n 1) m))))))
这是一个改进版本,可以带1个或2个参数;如果只给出一个,它的范围从0到给定的数字:
(define range
(lambda (n . m)
(let
((n (if (null? m) 0 n)) (m (if (null? m) n (car m))))
(cond
((= n m) (list n))
(else (cons n (range ((if (< n m) + -) n 1) m)))))))
答案 2 :(得分:3)
如果没有内置任何内容,那么编写自己的内容是非常简单的:
(define (range first last)
(if (>= first last)
'()
(cons first (range (+ first 1) last))))
答案 3 :(得分:3)
Racket中有一个内置的range函数,其行为类似于Python。
> (range 10)
'(0 1 2 3 4 5 6 7 8 9)
答案 4 :(得分:1)
我只是将@Ankur的评论提升为答案。在Racket中,你有“范围内”:
#lang racket
(in-range 7) ;; produces #<stream>
;; used in a loop:
(for/list ([i (in-range 7)])
i)
;; produces (list 0 1 2 3 4 5 6)
;; and, for the lazy among us:
(for/list ([i 7])
i)
;; produces the same
它也可以接受下限,增量(包括负数)等。
答案 5 :(得分:0)
没有找到我想要的东西,也不想使用外部软件包,我最终写了自己的版本,该版本与python版本不同(希望对此有所改进)。如果您认为它确实效率低下并且可以改进它,请这样做。
;; A version of range taking the form (range [[first] last [[step]]] ).
;; It takes negative numbers and corrects STEP to the same direction
;; as FIRST to LAST then returns a list starting from FIRST and
;; ending before LAST
(define (range . args)
(case (length args)
( (0) '())
( (1) (range 0 (car args) (if (negative? (car args)) -1 1)))
( (2) (range (car args) (cadr args)
(if (>= (car args) (cadr args)) -1 1)))
( (3) (let* ((start (car args)) (end (cadr args))
(step (if (> start end)
(- (abs (caddr args)))
(abs (caddr args)))))
(let loop ((x start) (xs '()))
(cond ((and (>= end start) (<= (abs end) (abs x)))
(reverse xs))
((and (<= end start) (>= (abs end) (abs x)))
(reverse xs))
(else (loop (+ x step) (cons x xs)))))))
(else (error 'range "too many arguments"))))
; (else (display "ERROR: range too many arguments") (newline)))) ;;r4rs
;; (range-inc [[first] last [[step]]] ) includes LAST in the returned range
(define (range-inc . args)
(case (length args)
( (0) '())
( (1) (append (range (car args)) args))
( (2) (append (range (car args) (cadr args)) (cdr args)))
( (3) (append (range (car args) (cadr args) (caddr args))
(list (cadr args))))
(else (error 'range "too many arguments"))))
; (else (display "ERROR: range too many arguments") (newline)))) ;;r4rs
请注意,我也写了common lisp版
答案 6 :(得分:0)
在GermánDiago发表评论之后,我为此做了一个纯粹的功能性懒惰版本(即流)。它可以构造一个您的Scheme实现可以在恒定时间内处理的任意大小的范围流,还可以在恒定时间内访问当前元素并推进该流。
(define ^range
(lambda (x y getter)
(op x y getter)))
(define EOS ; End of stream for finite streams
(^range '() '() (lambda () EOS)))
(define range
(lambda (x . y) ; if y < x then stream is infinite
(let ((x (if (null? y) 0 x))
(y (if (null? y) x (car y))))
(^range x y (lambda ()
(if (= x y) EOS
(range (+ x 1) y)))))))
(define get ; Get current element
(lambda (r)
(r (lambda (x y g) x))))
(define next ; Get stream for next element
(lambda (r)
(r (lambda (x y g) (g)))))
使用此代码:
> (define r (range 1 3))
> (get r)
1
> (get (next r))
2
> (get (next (next r)))
3
> (get (next (next (next r)))) ; EOS
()