gpt4 book ai didi

append - LISP 列表不 append 和打印两次

转载 作者:太空宇宙 更新时间:2023-11-03 19:03:02 29 4
gpt4 key购买 nike

我是 LISP 的新手,我正在尝试处理类的 cond 语句。目前,我正在尝试检查传递的值是否为列表,如果是,则将字母 d append 到列表中。

这是我的代码:

(defun test(L)
(listp L)
(cond ((listp L) (append L (list 'd)))
)
(write L)
)
(test (list 'a 'b 'c))

我得到的输出是:

(A B C)

(A B C)

如果我将测试更改为:(test (car(list 'a 'b 'c)))

我得到的新输出是:

A

A

我想知道的两件事是

1.) 如果第一个测试通过列表,为什么不将 D append 到列表中?

2.) 为什么要打印两次?我正在使用 LISP Works,所以我认为它实际上与它如何始终输出最终值或其他东西有关。

最佳答案

1.)同理str + "d"不突变str在 Java 或 Python 中。它会创建一个您不使用的新列表!

>>> str + "d"
'abcd'
>>> str
'abc'

疯狂的相似不是吗?

2.) 在 CL 中 return是最后计算的表达式。 REPL 将每个顶级表达式结果打印到终端。 Python 也这样做:

>>> def test():
... x = 2 + 3
... print x
... return x
...
>>> test()
5
5

更新

如何改变参数列表。简单的答案是你需要改变最后一对参数:

(defun test (l)
(assert (consp 1) (l) "l needs to be a non nil list. Got: ~a" l)
(nconc l (list 'd)
(write l)))

(defparameter *test1* (list 1 2 3))
(defparameter *test1-copy* *test1*)
(test *test1*) ; ==> (1 2 3 d) (and prints (1 2 3 d))
*test1* ; ==> (1 2 3 d)
*test1-copy* ; ==> (1 2 3 d)
(eq *test1* *test1-copy*) ; ==> t

(test '())
** error l needs to be a non nil list. Got: NIL

(nconc l x)(setf (cdr (last l)) x)

如果你需要改变绑定(bind),那么你需要制作一个宏:

(defmacro testm (var)
(assert (symbolp var) (var) "List needs to be a variable binding. Got: ~a" var)
`(progn
(when (listp ,var)
(setf ,var (append ,var (list 'd)))
(write ,var))))

(macroexpand '(testm *test2*))
; ==> (progn
; (when (consp *test2*)
; (setf *test2* (append *test2* (list 'd))))
; (write *test2*))

(defparameter *test2* (list 1 2 3))
(defparameter *test2-copy* *test2*)
(testm *test2*) ; ==> (1 2 3 d) (and prints (1 2 3 d))
*test2* ; ==> (1 2 3 d)
*test2-copy* ; ==> (1 2 3)
(eq *test2* *test2-copy*) ; ==> nil

(defparameter *x* nil)
(testm *x*) ; ==> (d) (and prints (d))
*x* ; ==> (d)

(testm '(1))
** error List needs to be a variable binding. Got: '(1)

惯用的方式来做到这一点

(defun test (list)
(if (consp list)
(append list '(d))
list))

(write (test '(1 2 3)))
; ==> (1 2 3 d) (and prints (1 2 3 d))

(defparameter *test3* '(1 2 3))
(setf *test3* (test *test3*))
*test3* ; ==> (1 2 3 d)

关于append - LISP 列表不 append 和打印两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46143225/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com