2013-04-16 32 views
14

Czy istnieje wzorzec pakietu lub języka w R, który ułatwia lub zapewnia implementację "Python-like generators"?Funkcje generatora w R

Przez „generatory Pythona typu” mam na myśli funkcje, które utrzymują stan pomiędzy rozmowami, w składni R i zaciągania słowa kluczowego wydajność z Pythona będzie coś takiego:

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

Z wydajnością zamiast powrót, to wywołanie funkcji trzykrotnym dałby:

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

Edycja: wyszedłem z AS pekty generatorów Pythona, które odróżniają je od iteratorów. Jest to, że cała lista obiektów do iteracji nie jest budowana na pierwszym wywołaniu, a następnie iterowana, ale każde wywołanie funkcji tworzy jeden element, który zwróci dla tego wywołania.

+1

R stara się być język funkcjonalny. Ta prośba może być spełniona tylko poprzez podejście niefunkcjonalne. Możesz przekreślić funkcjonalność za pomocą '<< -' jeśli to konieczne, ale prawdopodobnie lepiej jest pomyśleć o tym, co chcesz osiągnąć, i znaleźć funkcjonalne rozwiązanie. –

+0

Podobne pytanie: http://stackoverflow.com/questions/23509381/lazy-sequences-in-r – cbare

+0

Luke Tierney napisał także [Lazy List Implementation] (http://homepage.cs.uiowa.edu/~ luke/R/lazy/lazy.pdf). – cbare

Odpowiedz

15

Pakiet iterators ma tę funkcjonalność

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

Albo można użyć lambda.r i <<-. Przykład ten jest modyfikowany

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

istnieje więcej przykładów w blogu

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 

Zauważ, że można też użyć zwykłej funkcji, aby to zrobić.

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 

Jeśli chcesz wybrać z listy możliwych, wtedy być może to zrobić za pomocą 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

Dzięki za odpowiedź, niestety iterator nie jest tym o czym mówiłem i myślę, że nie wyjaśniłem tego dla tych, którzy nie znają funkcji generatora Pythona. – papirrin

+0

@papirrin - zobacz moją edycję. – mnel

+0

Dobra edycja, to nawet odpowiedź na pytania, których nie zrobiłem. – papirrin

Powiązane problemy