# Is it possible to update Array elements in a list comprehension?

I found list comprehension is very useful tool.

Currently I encountered a problem. Say there is an array of 5 integers named TEST. I want to add 1 to randomly selected elements of TEST for 10 times and see if there is a zero in the result.

I can do it in a normal loop, but my question is if I can do it using comprehension?

``````julia> TEST = zeros(Int,5)
5-element Array{Int64,1}:
0
0
0
0
0

#if I do the following, a error message jumps.
julia> TEST[rand(1:5)] += 1 for i in 1:10
ERROR: syntax: extra token "for" after end of expression
Stacktrace:
 top-level scope at REPL:1
 include_string(::Function, ::Module, ::String, ::String)

# and if I enclose the expression with (), it returns a generator.
julia> (TEST[rand(1:5)] += 1 for i in 1:10)
Base.Generator{UnitRange{Int64},var"#43#44"}(var"#43#44"(), 1:10)

``````

Try enclosing the expression in square brackets.

``````[TEST[rand(1:5)] += 1 for i in 1:10]
``````

In Julia, they’re called ‘array comprehensions’.

Thanks a lot for your quick response. I think it solved my problem! Note that using an array comprehension for this allocates an unnecessary array; it would be simpler and faster to use a loop:

``````for i = 1:10
TEST[rand(1:5)] += 1
end
``````

or, if you care about performance, put it in a function:

``````function randinc!(a, trials)
r = eachindex(a)
for i = 1:trials
a[rand(r)] += 1
end
return a
end
``````

and then call `randinc!(TEST, 10)`.

There’s nothing wrong with loops in Julia. Loops are fast and often convenient!

(Just noticed that you already realized this. I’m not sure why you want to use a comprehension for this?)

You may also be thinking of a generator expression, which you can create by using parentheses:

``````julia> (TEST[rand(1:5)] += 1 for i in 1:10)
Base.Generator{UnitRange{Int64},var"#11#12"}(var"#11#12"(), 1:10)
``````

A generator expression doesn’t actually perform the loop, however; it merely returns an iterator that can be passed an argument to another function that performs the loop, such as `foreach` or `sum`:

``````julia> sum(TEST[rand(1:5)] += 1 for i in 1:10)
17

julia> foreach(identity, TEST[rand(1:5)] += 1 for i in 1:10)
``````

(When it is passed as an argument, a generator expression doesn’t need the extra parentheses.)

It’s not clear what the point of using a generator, rather than a simple loop, would be in the contest, however.

4 Likes