2013-04-16 3 views
14

Gibt es ein Paket oder Sprachkonstrukt in R, das die Implementierung von "Python-like generators" erleichtert oder bereitstellt?Generatorfunktionen in R

Mit "Python-like-Generatoren" Ich Funktionen bedeuten, den Staat zwischen den Anrufen zu halten, in R Syntax und borgen das Schlüsselwort Ausbeute von Python wird so etwas wie sein:

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

Mit Ausbeute statt eine Rückkehr, dann würde die Funktion dreimal hintereinander Aufruf geben:

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

Edit: ich ein als links aus Python-Generatoren, die sie von Iteratoren unterscheiden. Die gesamte Liste der zu iterierenden Objekte wird nicht beim ersten Aufruf erstellt und dann iteriert. Bei jedem Funktionsaufruf wird jedoch das eine Element erstellt, das für diesen Aufruf zurückgegeben wird.

+1

R versucht, eine funktionale Sprache zu sein. Diese Anforderung kann nur durch einen nichtfunktionalen Ansatz erfüllt werden. Sie können die Funktionalität bei Bedarf mit "<< -" unterwandern, aber es ist wahrscheinlich besser, sich das Endziel vorzustellen und eine funktionierende Lösung zu finden. –

+0

Ähnliche Fragen: http://stackoverflow.com/questions/23509381/lazy-sequences-in-r – cbare

+0

Auch Luke Tierney schrieb eine [Lazy List Implementierung] (http://homepage.cs.uiowa.edu/~ luke/R/faul/faul.pdf). – cbare

Antwort

15

Das iterators Paket hat diese Funktionalität

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

Oder könnten Sie lambda.r und <<- verwenden. Dieses Beispiel ist aus modifizierten

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

gibt weitere Beispiele in der Blog-Post

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 

Bedeutung sind, dass Sie auch eine reguläre Funktion, dies zu tun verwenden könnten.

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 

Wenn Sie von einer möglichen Liste auswählen möchten, dann könnte man vielleicht so tun mit 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

Danke für deine Antwort, leider ist ein Iterator nicht das, worüber ich gesprochen habe, und ich denke, ich habe es nicht für diejenigen, die mit Python-Generatorfunktionen nicht vertraut sind, klar gemacht. – papirrin

+0

@papirrin - siehe meine Bearbeitung. – mnel

+0

Nice edit, es beantwortet sogar die Fragen, die ich nicht getan habe. – papirrin