LISP。创建对列表

时间:2015-11-26 21:45:12

标签: list lisp common-lisp

我有一个如下代码。它返回列表为(((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))))))
        )
    )   

)

1 个答案:

答案 0 :(得分:1)

首先:

(setf hod '())

这是定义全局变量的一种不好的方法;尝试

(defparameter hod ())

但为什么要使用全局变量呢?该函数可以构造一个新列表并返回它。如果调用者想要将其粘贴到全局变量中,则由调用者决定;它与函数的操作无关。

(defun generHod ...)

在默认的readtable下,语法generHod与Common Lisp中的GENERHODgenerhod不区分。所有这些令牌都产生相同的符号。最好不要用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)))))))