【问题标题】:LISP modify list passed as argumentLISP 修改列表作为参数传递
【发布时间】:2013-11-08 00:31:40
【问题描述】:

所以我得到了这个函数,它接收一个列表作为参数

(defun do-transf (lst)

...

我最初的 lst 是 ((NIL NIL) (NIL NIL)) 但最后我希望 lst 变成

(零零零零)

例子

(defvar a (list (list NIL NIL) (list NIL NIL)))

(do-transf a)

(NIL NIL NIL NIL) -> 给出了正确的答案,但是当我调用列表时,这不是答案

一个

((NIL NIL) (NIL NIL)) -> 我不想要这个

【问题讨论】:

  • 我知道您希望这具有破坏性(来自答案之一的 cmets),但究竟如何?在第一种情况下,a 是两个元素的列表(每个元素都等于(nil nil),但我们暂时称它们为xy)。所以a(x . (y . nil)),即由两个cons 单元组成的列表,我们称它们为xcyc。您想要的结果是(n1 . (n2 . (n3 . (n4 . nil))))n 代表nil),这是一个由四个 cons 单元格组成的列表。 xcyc 可以重复使用,但是另外两个从哪里来?

标签: lisp common-lisp


【解决方案1】:

您的帖子建议您希望进行列表连接,即将列表附加到另一个列表。

因此,试试这个:

(defvar a (list (list NIL NIL) (list NIL NIL)))
(apply #'append a)

这个输出:

(NIL NIL NIL NIL)

简短、简单、甜美。

更新:

既然你想要破坏性行为(即修改a的原始值):

(setq a (apply #'append a))

现在,a 设置为这个新值(来自 ((NIL NIL) (NIL NIL))):

(NIL NIL NIL NIL)

【讨论】:

  • @user2967111:你想要破坏性行为吗?也就是你想修改a?
  • @user2967111:这种行为正确。很少有 LISP 函数曾经需要您修改某些东西的值。 LISP 的做事方式是对输入的数据进行操作,然后返回修改后的数据。
  • (defun bla (lst) (setq lst (apply #'append a))) (defvar a (list (list NIL NIL) (list NIL NIL)) (bla a) (NIL NIL NIL NIL) a ((NIL NIL) (NIL NIL)) 列表保持不变..
  • 抱歉,我还不能回答我的问题
  • @user2967111:你刚才写的东西有很多问题。 很多。请不要采取错误的方式,但我认为您应该查看一个好的 LISP 源代码,以便在学习的同时更好地理解该语言。祝你好运。
【解决方案2】:

通常,lisp 函数不会改变它们操作的数据。这不是必需的属性,但它确实使编写和推理大型代码库变得更加容易。

因此,通常情况下,函数将返回新数据的副本,然后可以根据调用者的判断替换变量中的旧值。

即使函数破坏性地修改数据结构,它们也倾向于返回新的结果值。

如果我们看下面的代码:

(defvar *example* '(delete 2 3 4))
=> *example*
(delete 'delete *example*)
=> (2 3 4)
*example*
=> (delete 2 3 4)

这是因为没有函数可以破坏性地修改*example*,所以它会丢失第一个元素,所以即使你使用破坏性的变异函数,它们也需要返回一个值适合存储回输入来自的变量中。

【讨论】:

    【解决方案3】:

    尝试使用扁平化..

    (defvar a (flatten (list (list NIL NIL) (list NIL NIL))))
    

    【讨论】:

    • 这不是重点,我知道如何从 ((NIL NIL) (NIL NIL)) 到 (NIL NIL NIL NIL) 我想要的是列表变成那样
    猜你喜欢
    • 2013-12-16
    • 1970-01-01
    • 2023-03-12
    • 2020-07-16
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    相关资源
    最近更新 更多