如何在Lisp中获得点对?

时间:2011-01-31 04:11:48

标签: list lisp common-lisp

我已经搜索谷歌和其他地方一段时间,但我无法找到如何生成或创建点对。我问这个是因为,我需要打开一个如下所示的列表:

(X Y Z)

使用以下格式的列表:

((X . 1) (Y . 2) (Z . 3))

数字代表索引。我有一个函数将列表转换为

的格式
(X 1 Y 2 Z 3)

这是该功能:

  (defun listFormat (l)
     (defun place-index (idx l)
        (if (null l)
          nil
          (append (list (first l)) (list idx)
                  (place-index (+ idx 1) (rest l)))))
     (place-index 1 l))

但我不确定如何获得点对。 提前致谢

3 个答案:

答案 0 :(得分:11)

您的代码有一个非常基本的错误:

(defun listFormat (l)
     (defun place-index (idx l)    ; <<<---- This DEFUN is wrong
        (if (null l)
          nil
          (append (list (first l)) (list idx)
                  (place-index (+ idx 1) (rest l)))))
     (place-index 1 l))

不要嵌套DEFUN。这只是错误。 DEFUN定义了一个全局函数。每当您运行listFormat时,它都会重新定义 GLOBAL 函数PLACE-INDEX。您可能已使用DEFINE在SCHEME中看到过类似的嵌套函数。在Common Lisp中,您不应该将DEFUN用于嵌套的本地函数。

在Lisp中,本地函数使用FLET或LABELS定义(对于递归函数)。

(defun listFormat (l)
   (labels ((place-index (idx l)
              (if (null l)
                  nil
                  (append (list (first l)) (list idx)
                          (place-index (+ idx 1) (rest l))))))
       (place-index 1 l)))

Stackoverflow也是解决你的功课的错误地方。谷歌搜索也是学习Lisp编程的错误方法。

我建议使用旧的方式阅读介绍性书籍并使用参考文献。

这是一本基本的介绍性Lisp书籍供下载:Common Lisp: A Gentle Introduction to Symbolic Computation

参考表:小Common Lisp Quick Reference(PDF)和更详细的Common Lisp Quick Reference

在Lisp中将虚线对称为 conses

请参阅Common Lisp的真实在线参考,Common Lisp HyperSpec

答案 1 :(得分:6)

你想要else分支阅读:

(cons (cons (first l) idx) (place-index (+ idx 1) (rest l)))

答案 2 :(得分:1)

顺便说一下,对于问题本身,这段代码将会:

(defun listFormat (lst)
  (loop for idx from 1
        for item in lst
        collect (cons item idx)))