我有一个如下代码。它返回列表为(((1 . 2) (1 . 0)) ((1 . 2) (1 . 1)) ((1 . 2) (1 . 3)) ((1 . 2) (1 . 4)) ((1 . 2) (1 . 5)) ((1 . 2) (1 . 6)) ((1 . 2) (1 . 7)) ((1 . 2) (0 . 2)) ((1 . 2) (2 . 2)))
我想知道我是否可以重写generHod函数,使其返回列表((1.2 1.0) (3.4 4.2) (1.3 1.3)...)
(setf hod '())
(defun generHod (CurrX CurrY)
(dotimes (y 8)
(if (/= y CurrY)
(setf hod (append hod (list (append (list (cons CurrX CurrY))(list (cons CurrX y))))))
)
)
(dotimes (x 8)
(if (/= x CurrX)
(setf hod (append hod (list (append (list (cons CurrX CurrY))(list (cons x CurrY))))))
)
)
)
答案 0 :(得分:1)
首先:
(setf hod '())
这是定义全局变量的一种不好的方法;尝试
(defparameter hod ())
但为什么要使用全局变量呢?该函数可以构造一个新列表并返回它。如果调用者想要将其粘贴到全局变量中,则由调用者决定;它与函数的操作无关。
(defun generHod ...)
在默认的readtable下,语法generHod
与Common Lisp中的GENERHOD
或generhod
不区分。所有这些令牌都产生相同的符号。最好不要用Lisp标识符来玩混合大小写游戏;如果你想要多个单词,请加上像gen-hod
这样的短划线。通常generate
被英语黑客一直缩写为gen
,而不是gener
。例如,请参阅Common Lisp中的gensym
功能。
在您的函数中,有一个完全多余的append
:
(append
(list (cons CurrX CurrY))
(list (cons CurrX y))))
模式(append (list X0) (list X1) ... (list XN))
可以重写(list X0 X1 ... XN)
。你制作多余的东西只是为了将它们组合在一起制作一个列表,而不是仅仅列出这些东西。
要获取从整数到浮点的值,可以使用float
函数,loop
宏提供迭代和收集项的习惯用法:
(defun gen-hod (curr-x curr-y)
(let ((cxy (list (float curr-x) (float curr-y)))) ;; allocate just once!
(nconc ;; destructive append: use with care
(loop for y from 1 to 8
when (/= y curr-y)
append (list cxy (list (float curr-x) (float y))))
(loop for x from 1 to 8
when (/= x curr-x)
append (list cxy (list (float x) (float curr-y)))))))