从 lapply 返回匿名函数 - 出了啥问题?

Posted

技术标签:

【中文标题】从 lapply 返回匿名函数 - 出了啥问题?【英文标题】:Returning anonymous functions from lapply - what is going wrong?从 lapply 返回匿名函数 - 出了什么问题? 【发布时间】:2013-03-22 10:51:51 【问题描述】:

当尝试使用lapply 创建类似函数的列表时,我发现列表中的所有函数都是相同的,并且与最终元素应该是相同的。

考虑以下几点:

pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl
[[1]]
function (x) 
pow(x, y)
<environment: 0x09ccd5f8>

[[2]]
function (x) 
pow(x, y)
<environment: 0x09ccd6bc>

[[3]]
function (x) 
pow(x, y)
<environment: 0x09ccd780>

当您尝试评估这些函数时,您会得到相同的结果:

pl[[1]](2)
[1] 8
pl[[2]](2)
[1] 8
pl[[3]](2)
[1] 8

这里发生了什么,我怎样才能得到我想要的结果(列表中的正确函数)?

【问题讨论】:

我不确定,你的目标是什么。也许pl &lt;- function(x,y) lapply(y,function(y) pow(x,y)); pl(2,1:3) Ross Ihaka (RCore) 的这些笔记可能会有所帮助(特别是关于惰性评估的部分)www.stat.auckland.ac.nz/~ihaka/downloads/Waikato-WRUG.pdf 请注意,从 R 3.2.0 开始,这不再适用,请参阅下面的答案。 【参考方案1】:

R 传递promises,而不是值本身。承诺在第一次评估时被强制执行,而不是在通过时,如果使用问题中的代码,到那时索引已经改变。代码可以写成force调用外部匿名函数时的promise,让读者看清楚:

pl <- lapply(1:3, function(y)  force(y); function(x) pow(x,y)  )

【讨论】:

谢谢,很高兴知道这个陷阱是如何工作的。以后我必须牢记这一点。【参考方案2】:

从 R 3.2.0 开始,这不再适用!

change log 中的对应行内容为:

高阶函数,例如 apply 函数和 Reduce() 现在 对它们应用的函数强制参数以消除 惰性求值和变量捕获之间的不良交互 在闭包中。

确实:

pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl[[1]](2)
# [1] 2
pl[[2]](2)
# [1] 4
pl[[3]](2)
# [1] 8

【讨论】:

以上是关于从 lapply 返回匿名函数 - 出了啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

C ++返回向量,无法弄清楚出了啥问题

Python 请求基本命令返回错误 - 出了啥问题?

python基础——匿名函数及递归函数

什么是透明匿名高匿代理?详解!

15 .内置函数,递归函数,二分法

匿名函数