Мы говорим о скорости, так что давайте делать некоторые бенчмаркинг:
library(microbenchmark)
microbenchmark(op = {for (i in 1:length(l1)) bar[l2[i]] <- foo(l1[i])},
lapply = setNames(lapply(l1,foo),l2),
vectorised = setNames(as.list(foo(l1)), l2))
Unit: microseconds
expr min lq mean median uq max neval
op 7.982 9.122 10.81052 9.693 10.548 36.206 100
lapply 5.987 6.557 7.73159 6.842 7.270 55.877 100
vectorised 4.561 5.132 6.72526 5.417 5.987 80.964 100
Но эти маленькие значения не значат , поэтому я накачал длину вектора до 10000, где вы действительно увидите разницу:
l <- 10000
l1 <- seq_len(l)
l2 <- sample(letters, l, replace = TRUE)
microbenchmark(op = {bar <- list(); for (i in 1:length(l1)) bar[l2[i]] <- foo(l1[i])},
lapply = setNames(lapply(l1,foo),l2),
vectorised = setNames(as.list(foo(l1)), l2),
times = 100)
Unit: microseconds
expr min lq mean median uq max neval
op 30122.865 33325.788 34914.8339 34769.8825 36721.428 41515.405 100
lapply 13526.397 14446.078 15217.5309 14829.2320 15351.933 19241.767 100
vectorised 199.559 259.997 349.0544 296.9155 368.614 3189.523 100
Но, ссылаясь на то, что говорили все остальные, это не обязательно должен быть список. Если вы удалите требование из списка:
microbenchmark(setNames(foo(l1), l2))
Unit: microseconds
expr min lq mean median uq max neval
setNames(foo(l1), l2) 22.522 23.8045 58.06888 25.0875 48.322 1427.417 100
'setNames (lapply (l1, foo), l2)'. – joran
Если вам это не нужно как список (потому что это всего лишь одно число на элемент), вы можете использовать 'sapply' вместо' lapply'. – Frank
Поскольку умножение (и, следовательно, 'foo') векторизовано, вы можете просто выполнить' as.list (setNames (l1 * 5, l2)) 'или' as.list (setNames (foo (l1), l2)) '; отмените 'as.list', чтобы сохранить его как именованный числовой вектор. – alistaire