将嵌套列表展平为 1 深列表

Posted

技术标签:

【中文标题】将嵌套列表展平为 1 深列表【英文标题】:Flatten nested list into 1-deep list 【发布时间】:2013-11-13 02:31:49 【问题描述】:

我正在寻找一种有效的解决方案来(递归地)将嵌套列表(任意深度)展平为非嵌套的 1 个深度列表。列表元素不是同质的,因此不应将它们未列出到向量中(这会将所有值强制为单一类型)。迄今为止最好的解决方案是:

flatlist <- function(mylist)
    lapply(rapply(mylist, enquote, how="unlist"), eval)

这几乎可以满足我的要求:

> flatlist(list(foo=TRUE, bar=456, pets=list(cat="meeuw", dog="woof")))
$foo
[1] TRUE

$bar
[1] 456

$pets.cat
[1] "meeuw"

$pets.dog
[1] "woof"

但是,一个问题是 rapply 正在丢弃 NULL 值,这是不希望的:

> flatlist(list(foo=123, bar=NULL))
$foo
[1] 123

我希望NULL 元素以NULLNA 的形式出现在输出中。还有enquoteeval 的双循环使事情变得有点慢。这个函数在我的代码中被广泛使用。有没有办法一次性完成所有操作?

【问题讨论】:

您几乎可以肯定地修改@Ferdinand.kraft's excellent answer to a similar question here 中的代码。事实上,看看那里的 cmets,您似乎已经看到了答案! 那个解决方案确实效率低下,可能是因为result &lt;- c(result, .....。我希望有更本土的东西。 很高兴知道。感谢您的澄清。 我建议检查this thread 【参考方案1】:

用您自己的递归替换rapply 部分,这样NULLs 就不会得到任何特殊处理:

renquote <- function(l) if (is.list(l)) lapply(l, renquote) else enquote(l)

lapply(unlist(renquote(ml)), eval)

【讨论】:

我想这是唯一正确的解决方案。它不如原生 rapply 快​​,但它会做。谢谢! 请注意,is.list() 也为 data.frames 返回 TRUE。或者使用: if( class(l) == 'list') ....

以上是关于将嵌套列表展平为 1 深列表的主要内容,如果未能解决你的问题,请参考以下文章

Erlang Lists:展平嵌套列表

将嵌套的 dict 列表展平为 Pandas Dataframe

as.data.frame 将嵌套列表展平为单行,而不是为每条记录创建行 [重复]

当列表包含另一个列表的 1 个单个项目时,展平嵌套列表

在 Erlang 中展平嵌套列表的列表

如何将嵌套列表的两个维度完全展平?