Package provides Python-style list comprehensions for R. List comprehension expressions use usual loops (for
, while
and repeat
) and usual if
as list producers. Syntax is very similar to Python. The difference is that returned value should be at the end of the loop body.
Rather unpractical example - squares of even numbers:
Pythagorean triples:
to_list(for (x in 1:20) for (y in x:20) for (z in y:20) if (x^2 + y^2 == z^2) c(x, y, z))
#> [[1]]
#> [1] 3 4 5
#>
#> [[2]]
#> [1] 5 12 13
#>
#> [[3]]
#> [1] 6 8 10
#>
#> [[4]]
#> [1] 8 15 17
#>
#> [[5]]
#> [1] 9 12 15
#>
#> [[6]]
#> [1] 12 16 20
More examples:
colours = c("red", "green", "yellow", "blue")
things = c("house", "car", "tree")
to_vec(for(x in colours) for(y in things) paste(x, y))
#> [1] "red house" "red car" "red tree" "green house"
#> [5] "green car" "green tree" "yellow house" "yellow car"
#> [9] "yellow tree" "blue house" "blue car" "blue tree"
# prime numbers
noprimes = to_vec(for (i in 2:7) for (j in seq(i*2, 99, i)) j)
primes = to_vec(for (x in 2:99) if(!x %in% noprimes) x)
primes
#> [1] 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83
#> [24] 89 97
You can iterate over multiple lists if you provide several loop variables in backticks:
to_vec(for(`i, j` in numerate(letters)) if(i %% 2==0) paste(i, j))
#> [1] "2 b" "4 d" "6 f" "8 h" "10 j" "12 l" "14 n" "16 p" "18 r" "20 t"
#> [11] "22 v" "24 x" "26 z"
set.seed(123)
rand_sequence = runif(20)
# gives only locally increasing values
to_vec(for(`i, j` in lag_list(rand_sequence)) if(j>i) j)
#> [1] 0.7883051 0.8830174 0.9404673 0.5281055 0.8924190 0.9568333 0.6775706
#> [8] 0.8998250 0.3279207 0.9545036