使用 set 修改列表的一部分?

发布于 2024-12-12 13:15:41 字数 405 浏览 1 评论 0原文

使用 set! 我希望能够修改本地状态 list 变量 lst,但只是其中的一部分

例如,我想在内部列表中插入值:

((1 2) (4 5))

变成

((1 2 3) (4 5))

我希望能够执行类似 set! 的操作! (car lst) (append (car lst) 3)

但这似乎只修改了 (car lst) 生成的临时变量。

我能想到的唯一方法是使用新的所需值创建一个新列表,并将 lst 设置为新列表,但这似乎浪费且不必要。有更好的方法吗?

Using set! I want to be able to modify a local state list variable lst, but only a part of it

For example, I want to insert values inside an inner list:

((1 2) (4 5))

becomes

((1 2 3) (4 5))

I want to be able to do something like set! (car lst) (append (car lst) 3)

But that seems to only modify the temporary variable generated by (car lst).

The only way I can think of is to create a new list with the new desired values and set lst to be the new list, but that seems wasteful and unnecessary. Is there a better way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我的鱼塘能养鲲 2024-12-19 13:15:41

试试这个:

(define lst (list (list 1 2) (list 4 5)))
lst
> ((1 2) (4 5))
(set-cdr! (cdar lst) (list 3))
lst
> ((1 2 3) (4 5))

当修改 cons/lists 时,你应该使用 set-cdr!和定车!

编辑:对于球拍

使用可变列表:

(require racket/mpair)
(define lst (mlist (mlist 1 2) (mlist 4 5)))
lst
> (mcons (mcons 1 (mcons 2 '())) (mcons (mcons 4 (mcons 5 '())) '()))
(set-mcdr! (mcdr (mcar lst)) (list 3))
> (mcons (mcons 1 (mcons 2 #<promise:temp2>)) (mcons (mcons 4 (mcons 5 '())) '()))
lst

try this:

(define lst (list (list 1 2) (list 4 5)))
lst
> ((1 2) (4 5))
(set-cdr! (cdar lst) (list 3))
lst
> ((1 2 3) (4 5))

when modifying cons/lists you should use set-cdr! and set-car!

EDIT: for racket

use mutable list:

(require racket/mpair)
(define lst (mlist (mlist 1 2) (mlist 4 5)))
lst
> (mcons (mcons 1 (mcons 2 '())) (mcons (mcons 4 (mcons 5 '())) '()))
(set-mcdr! (mcdr (mcar lst)) (list 3))
> (mcons (mcons 1 (mcons 2 #<promise:temp2>)) (mcons (mcons 4 (mcons 5 '())) '()))
lst
煮酒 2024-12-19 13:15:41

根据您使用的方案解释器,您可能需要做更多的工作。例如,在 Racket 中,列表基元默认情况下是可变的,您必须使用过程的可变版本:

(require scheme/mpair)
(define lst (mlist (mlist 1 2) (mlist 4 5)))
lst
(set-mcdr! (mcdr (mcar lst)) (mlist 3))
lst

Depending on which interpreter of Scheme you're using, you might need to do a bit more of work. For instance, in Racket the list primitives are not mutable by default, and you'll have to use the mutable version of the procedures:

(require scheme/mpair)
(define lst (mlist (mlist 1 2) (mlist 4 5)))
lst
(set-mcdr! (mcdr (mcar lst)) (mlist 3))
lst
我家小可爱 2024-12-19 13:15:41

在Scheme中创建列表的标准习惯用法是使用cons将元素添加到前面,而不是尝试set-cdr!列表中的最后一个cons单元格。最后,当列表完成后,您可以使用 reverse 以正确的顺序获取元素。这样,列表本身就不需要突变。

因此,如果您尝试逐步创建列表 (1 2 3)

  • 请从空列表、()cons 开始1 到它。这将为您提供 (1)
  • 然后将 cons 2 添加到列表中:(2 1)
  • 然后将 cons 3 添加到列表中:(3 2 1)
  • 最后,当您构建完列表后,将其反转:(1 2 3)

您可能会问为什么这样“更好”。这是因为访问 set-cdr! 的最后一对是一个 O(n) 操作;对于链表,元素不是随机访问的,而是在被访问的元素位置上是线性的。然而,cons 始终为 O(1)。

reverse 是一个 O(n) 操作,但只要您仅在最后执行此操作(当您准备好以正确的顺序构建列表时),而不是将其全部调用时间,这不会对性能产生不利影响。

The standard idiom in Scheme for creating a list piecemeal is to prepend elements to the front, using cons, and not trying to set-cdr! the last cons cell in the list. At the end, when your list is done, you can then use reverse to get the elements in the correct order. This way, no list mutation is necessary per se.

So if you're trying to create the list (1 2 3) piecemeal:

  • Start off with the empty list, (), and cons 1 to it. This gives you (1).
  • Then cons 2 to the list: (2 1)
  • Then cons 3 to the list: (3 2 1)
  • Finally, when you're done building the list, reverse it: (1 2 3)

You may ask why this is "better". That's because accessing the last pair to set-cdr! is an O(n) operation; with linked lists, elements are not random-access, but are linear on the element position being accessed. Whereas, cons is always O(1).

reverse is an O(n) operation, but as long as you're doing it only at the end (when you are ready to build the list in the correct order), rather than calling it all the time, that won't detrimentally affect performance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文