从 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 <- 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 返回匿名函数 - 出了啥问题?的主要内容,如果未能解决你的问题,请参考以下文章