我有如下代码。它返回列表为 (((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))))))
)
)
)
最佳答案
首先:
(setf hod '())
这种定义全局变量的方式很糟糕;尝试
(defparameter hod ())
但为什么要使用全局变量呢?该函数可以构造一个新列表并返回它。如果调用者想把它放到一个全局变量中,那取决于调用者;它与函数的操作无关。
(defun generHod ...)
语法generHod
与Common Lisp中的GENERHOD
或generhod
没有区别,在默认的可读表下。所有这些 token 都产生相同的符号。最好不要玩 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 的值,可以使用 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)))))))
关于list - 口齿不清。创建对列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33947448/