Common Lisp中的Python枚举()模拟

ssi*_*ice 4 common-lisp

我想映射列表,但要跟踪列表中的元素索引.

在Python中,我可以做一些事情:

map(lambda (idx, elt): "Elt {0}: {1}".format(idx, elt), enumerate(mylist))
Run Code Online (Sandbox Code Playgroud)

我试图将其翻译成以下内容:

(mapcar-something (lambda (elt idx) (format nil "Elt ~D: ~S" idx elt))
                  '(a b c d))
Run Code Online (Sandbox Code Playgroud)

预期结果:

("Elt 0: A" "Elt 1: B" "Elt 2: C" "Elt 3: D")
Run Code Online (Sandbox Code Playgroud)

但我找不到我应该使用的mapcar-something功能.我是否需要自己实现(通过循环,也许)?

Rai*_*wig 9

CL-USER 25 > (defun iota (n)
               (loop for i below n collect i))
IOTA

CL-USER 26 > (iota 4)
(0 1 2 3)

CL-USER 27 > (mapcar (lambda (elt idx)
                       (format nil "Elt ~D: ~S" idx elt))
                     '(a b c d)
                     (iota 4))
("Elt 0: A" "Elt 1: B" "Elt 2: C" "Elt 3: D")
Run Code Online (Sandbox Code Playgroud)

要么

CL-USER 28 > (loop for elt in '(a b c d) and idx from 0
                   collect (format nil "Elt ~D: ~S" idx elt))
("Elt 0: A" "Elt 1: B" "Elt 2: C" "Elt 3: D")
Run Code Online (Sandbox Code Playgroud)


ssi*_*ice 5

Common Lisp 的 LOOP 宏可以自动跟踪索引。

(loop for elt in '(a b c d) and idx from 0
      collect (operation-on idx elt))
Run Code Online (Sandbox Code Playgroud)

LOOP 自动将用;初始化的变量加1 from如果它们被引入,and那么两个赋值(数组的元素和索引)都会立即发生,而不是嵌套。

因此,枚举函数将类似于:

(defun enumerate (list &optional (first-index 0))
  (loop for elt in list and idx from first-index
    collect (cons idx elt)))
Run Code Online (Sandbox Code Playgroud)

在 Common Lisp 的表达能力中,按照以下方式定义宏可能会很有用:

(defmacro with-enumerated-list ((list elt idx &key (first-index 0)) &body body)
  `(loop for ,elt in ,list and ,idx from ,first-index
     collect (progn ,@body)))
Run Code Online (Sandbox Code Playgroud)

在这种情况下,枚举函数可以简化为:

(defun enumerate (list &optional (first-index 0))
  (with-enumerated-list (list elt idx :first-index first-index)
    (cons idx elt)))
Run Code Online (Sandbox Code Playgroud)