It frequently happens that I have a loop with ~10 lines. I’d like to return some value at the end of each iteration, collect that in an array, and then plot it. I can pre-allocate some array, or append to an array as the loop goes…but I’d like to do something like a list comprehension that just returns an array, without me worrying about its size or bothering to append. When the operation is something simple, and not 10 lines of code, I usually just do a list comprehension. How does one do a list comprehension when the thing you want to do to each iterate is 10 lines of code?
It seem like a do block might work for this but I’ve been messing around without success. Here’s a highly contrived MWE.
using Random
its = 10:2:30
out = []
for i in its
t = randperm(i)
s = maximum(t)
u = rand(s)[1]
append!(out,u)
end
plot(out)
I’d like to do this without using the ‘temporary’ out array
Something like:
its = collect(10:2:30)
?? do i
t = randperm(i)
s = maximum(t)
u = rand(s)[1]
end |> plot
I was pondering a similar problem when I posted this suggestion. Based on this answer, your contrived loop can be rewritten in list comprehension syntax as follows:
out = [rand(s)[1]
for i in 10:2:30
for t = Ref(randperm(i))
for s = Ref(maximum(t))]
Whether you prefer this, the for loop or the map syntax is a matter of taste.
Similar to the answer above, you can directly translate this to a comprehension (but no need to introduce artificial iterations, a begin or let block will let you pack multiple lines):
[ let
t = randperm(i)
s = maximum(t)
u = rand(s)[1]
end for i in its ]