# Can you define variables inside a comprehension?

``````julia> M = [1 2; 3 4]
2×2 Matrix{Int64}:
1  2
3  4

julia> M = (M + M') ./ 2.0
2×2 Matrix{Float64}:
1.0  2.5
2.5  4.0

julia> M = [1 2; 3 4]
2×2 Matrix{Int64}:
1  2
3  4

julia> [ x = (x + x') ./ 2.0 for x in [M] ]
1-element Vector{Matrix{Float64}}:
[1.0 2.5; 2.5 4.0]

julia> M
2×2 Matrix{Int64}:
1  2
3  4
``````

Is there a way to redefine/mutate a variable inside a comprehension?
Or are all things supposed to be always be local inside a comprehension?

You can change an existing variable from outer scope as follows:

``````julia> function f(outer_var)
[
begin
outer_var = i
end
for i in 1:100 ]
return outer_var
end
f (generic function with 1 method)

julia> f(1)
100
``````

As a matter of style, I’d say it’s better that way.

2 Likes

You can mutate a variable inside a comprehension but I wouldn’t recommend it as its very non-standard/confusing. If you really want to do it then

``````julia> M = [1.0 2; 3 4]
2×2 Matrix{Float64}:
1.0  2.0
3.0  4.0

julia> [x .= (x + x') ./ 2.0 for x in [M]]
1-element Vector{Matrix{Float64}}:
[1.0 2.5; 2.5 4.0]

julia> M
2×2 Matrix{Float64}:
1.0  2.5
2.5  4.0
``````

(Note that you need to get the type of `M` right to mutate it like this.)

If you don’t want the resulting collection, a much cleaner way would be to declare a function and broadcast over the array.

``````julia> dosomething!(x) = (x .= (x + x') ./ 2.0)
dosomething! (generic function with 1 method)

julia> M = [1.0 2; 3 4]
2×2 Matrix{Float64}:
1.0  2.0
3.0  4.0

julia> dosomething!.([M])
1-element Vector{Matrix{Float64}}:
[1.0 2.5; 2.5 4.0]

julia> M
2×2 Matrix{Float64}:
1.0  2.5
2.5  4.0
``````

or

``````julia> M = [1.0 2; 3 4]
2×2 Matrix{Float64}:
1.0  2.0
3.0  4.0

julia> foreach(x -> x .= (x + x') ./ 2.0, [M])

julia> M
2×2 Matrix{Float64}:
1.0  2.5
2.5  4.0
``````
3 Likes