2013-04-16 53 views
14

在R中是否有包或語言結構來促進或提供「Python-like generators」的實現?R中的生成器函數

通過「巨蟒般生成」我的意思是保持狀態的呼叫之間,R中的語法和Python的借款關鍵字產量將功能類似:

iterable.fun <- function(){ 
    yield list('a','b','c') 
} 

隨着產量代替一個回報,然後調用函數連續三次將給予:

> iterable.fun() 
    'a' 
> iterable.fun() 
    'b' 
> iterable.fun() 
    'c' 

編輯:我離開了一個爲Python生成器,使它們與迭代器不同。這是因爲要迭代的整個對象列表不是在第一次調用時構建的,然後進行迭代,但每個函數調用都會創建一個將針對該調用返回的元素。

+1

R期望是一個功能性的語言。該請求只能通過非功能性方法來實現。如有必要,您可以使用<< - - '來顛覆功能,但最好能夠考慮最終結果,並尋找功能性解決方案。 –

+0

類似的問題:http://stackoverflow.com/questions/23509381/lazy-sequences-in-r – cbare

+0

另外,Luke Tierney寫了一個[Lazy List Implementation](http://homepage.cs.uiowa.edu/~路加/ R /懶惰/ lazy.pdf)。 – cbare

回答

15

iterators包有此功能

library(iterators) 
abc <- iter(c('a','b','c')) 
nextElem(abc) 
## [1] "a" 
nextElem(abc) 
## [1] "b" 
nextElem(abc) 
## [1] "c" 

或者你可以使用lambda.r<<-。這個例子是從

http://cartesianfaith.wordpress.com/2013/01/05/infinite-generators-in-r/

修改有在博客文章

library(lambda.r) 
seq.gen(start) %as% { 
    value <- start - 1L 
    function() { 
    value <<- value + 1L 
    return(value) 
    } 
} 



foo <- seq.gen(1) 
foo() 
## [1] 1 
foo() 
## [1] 2 
foo() 
## [1] 3 

注意到更多的例子,你也可以使用常規的功能做到這一點。

seq.gen <-function(start) { 
    value <- start - 1L 
    function() { 
    value <<- value + 1L 
    return(value) 
    } 
} 
foo2 <- seq.gen(1) 
foo2() 
## [1] 1 
foo2() 
## [1] 2 
foo2() 
## [1] 3 

如果你想從一個可能的列表中進行選擇,那麼你也許可以做到使用switch

seq.char(start) %as% { 
    value <- start - 1L 
    function() { 
    value <<- value + 1L 
    return(switch(value,'a','b','c')) 
    } 
} 

foo.char <- seq.char(1) 
foo.char() 
## [1] "a" 
foo.char() 
## [1] "b" 
foo.char() 
## [1] "c" 
+0

感謝您的回答,不幸的是迭代器不是我正在談論的內容,我想我對那些不熟悉Python生成器函數的人沒有說清楚。 – papirrin

+0

@papirrin - 看我的編輯。 – mnel

+0

好的編輯,它甚至回答我沒有做的問題。 – papirrin