Mir*_*lov 29 python common-lisp number-sequence
如何在Common Lisp中创建连续数字列表?
换句话说,什么是相同的Python range在Common Lisp中的功能?
在Python中range(2, 10, 2)返回[2, 4, 6, 8],第一个和最后一个参数是可选的.虽然Emacs Lisp有,但我找不到创建数字序列的惯用方法number-sequence.
可以使用循环宏来模拟范围,但我想知道生成具有起点和终点以及步骤的数字序列的可接受方式.
Vat*_*ine 35
没有内置的生成数字序列的方法,这样做的规范方法是执行以下操作之一:
looploop一个示例实现是(这只接受从"低"到"高"的计数):
(defun range (max &key (min 0) (step 1))
(loop for n from min below max by step
collect n))
Run Code Online (Sandbox Code Playgroud)
这允许您指定(可选)最小值和(可选)步长值.
要生成奇数: (range 10 :min 1 :step 2)
小智 17
亚历山大港实施方案的iota:
(ql:quickload :alexandria)
(alexandria:iota 4 :start 2 :step 2)
;; (2 4 6 8)
Run Code Online (Sandbox Code Playgroud)
小智 5
这是我如何处理这个问题:
(defun generate (from to &optional (by 1))
#'(lambda (f)
(when (< from to)
(prog1 (or (funcall f from) t)
(incf from by)))))
(defmacro with-generator ((var from to &optional (by 1)) &body body)
(let ((generator (gensym)))
`(loop with ,generator = (generate ,from ,to ,by)
while
(funcall ,generator
#'(lambda (,var) ,@body)))))
(with-generator (i 1 10)
(format t "~&i = ~s" i))
Run Code Online (Sandbox Code Playgroud)
但这只是一般的想法,还有很大的改进空间.
好的,因为这里似乎有一个讨论.我假设真正需要的是类似于Python的range生成器函数.在某种意义上,它生成一个数字列表,但通过每次迭代产生一个数字来做到这一点(因此它不会一次创建多个项目).生成器是一个有点罕见的概念(很少有语言实现它),所以我假设提到Python表明需要这个确切的特性.
在对上面的例子进行一些批评之后,这里有一个不同的例子,说明为什么可以使用生成器而不是简单的循环.
(defun generate (from to &optional (by 1))
#'(lambda ()
(when (< from to)
(prog1 from
(incf from by)))))
(defmacro with-generator
((var generator &optional (exit-condition t)) &body body)
(let ((g (gensym)))
`(do ((,g ,generator))
(nil)
(let ((,var (funcall ,g)))
(when (or (null ,var) ,exit-condition)
(return ,g))
,@body))))
(let ((gen
(with-generator (i (generate 1 10) (> i 4))
(format t "~&i = ~s" i))))
(format t "~&in the middle")
(with-generator (j gen (> j 7))
(format t "~&j = ~s" j)))
;; i = 1
;; i = 2
;; i = 3
;; i = 4
;; in the middle
;; j = 6
;; j = 7
Run Code Online (Sandbox Code Playgroud)
这再一次只是这个功能的目的的说明.使用它来生成整数可能是浪费,即使你需要分两步完成,但生成器最适合使用解析器,当你想要产生一个更复杂的对象时,它是根据解析器的先前状态构建的,例如,还有很多其他的东西.那么,你可以在这里阅读一个关于它的论点:http://en.wikipedia.org/wiki/Generator_%28computer_programming%29
使用递归:
(defun range (min max &optional (step 1))
(when (<= min max)
(cons min (range (+ min step) max step))))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8845 次 |
| 最近记录: |