在摊销常数时间内将对象附加到 R 中的列表,O(1)?摊销、常数、内将、对象

2023-09-07 02:03:08 作者:冷心人i

如果我有一些 R 列表 mylist,您可以像这样将项目 obj 附加到它:

If I have some R list mylist, you can append an item obj to it like so:

mylist[[length(mylist)+1]] <- obj

但肯定有一些更紧凑的方法.当我是 R 的新手时,我尝试像这样编写 lappend():

But surely there is some more compact way. When I was new at R, I tried writing lappend() like so:

lappend <- function(lst, obj) {
    lst[[length(lst)+1]] <- obj
    return(lst)
}

但由于 R 的按名称调用语义,这当然不起作用(lst 在调用时被有效复制,因此对 lst 的更改在外部不可见lappend() 的范围.我知道你可以在 R 函数中进行环境黑客攻击,以达到你的函数范围之外并改变调用环境,但这似乎是一个大锤子来编写一个简单的附加函数.

but of course that doesn't work due to R's call-by-name semantics (lst is effectively copied upon call, so changes to lst are not visible outside the scope of lappend(). I know you can do environment hacking in an R function to reach outside the scope of your function and mutate the calling environment, but that seems like a large hammer to write a simple append function.

任何人都可以提出一种更漂亮的方法吗?如果它适用于向量和列表,则加分.

Can anyone suggest a more beautiful way of doing this? Bonus points if it works for both vectors and lists.

推荐答案

如果是字符串列表,使用c()函数即可:

If it's a list of string, just use the c() function :

R> LL <- list(a="tom", b="dick")
R> c(LL, c="harry")
$a
[1] "tom"

$b
[1] "dick"

$c
[1] "harry"

R> class(LL)
[1] "list"
R> 

这也适用于矢量,所以我可以获得奖励积分吗?

That works on vectors too, so do I get the bonus points?

编辑(2015 年 2 月 01 日): 这篇文章即将迎来它的五岁生日.一些善良的读者不断重复它的任何缺点,所以一定要看看下面的一些评论.list 类型的一个建议:

Edit (2015-Feb-01): This post is coming up on its fifth birthday. Some kind readers keep repeating any shortcomings with it, so by all means also see some of the comments below. One suggestion for list types:

newlist <- list(oldlist, list(someobj))

一般来说,R 类型很难为所有类型和用途使用一个且只有一个习语.

In general, R types can make it hard to have one and just one idiom for all types and uses.