# Looping over variables names properly

**URL:** <https://discourse.julialang.org/t/looping-over-variables-names-properly/80468>\
**Category:** General Usage\
**Tags:** question\
**Created:** [May 4, 2022, 8:28am UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468 "2022-05-04T08:28:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)\
**Post date:** [May 4, 2022, 8:28am UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/1 "2022-05-04T08:28:44Z")

</div>

I have a few arrays, say `x`, `y`, `z`, and I want to take all of their means and put them into new variables as `x_mean = mean(x)`.  
Is there a way to do this in a for loop? Something like

```julia
for a in ["x", "y", "z"]
    $a_mean = mean($a)
end

```

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [May 4, 2022, 8:40am UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/2 "2022-05-04T08:40:36Z")

</div>

You can do it with `@eval`:

```julia
julia> using Statistics: mean

julia> x, y, z = rand(3), rand(3), rand(3);

julia> for a in [:x, :y, :z]
           @eval $(Symbol(a, "_mean")) = mean($a)
       end

julia> x_mean
0.7142450574816145

```

Most of the time this is not a great idea though and you would be better off organizing your data differently, but it depends on how you are using it.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [May 4, 2022, 9:03am UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/3 "2022-05-04T09:03:46Z")

</div>

You could build something like a `Dict` that maps variable names to their mean

```julia
julia> d = Dict(name=>mean(val) for (name, val) in pairs((; x,y,z)))
Dict{Symbol, Float64} with 3 entries:
  :y => 0.189552
  :z => 0.744915
  :x => 0.551346

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [May 5, 2022, 4:26pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/4 "2022-05-05T16:26:43Z")

</div>

It looks like exactly what you do using packages like DataFrames or InMemoryDataset

```julia
ulia> df=DataFrame(x=rand(-50:50,10),y=rand(-5:5,10),z=rand(-10:10,10))
10×3 DataFrame
 Row │ x y z     
     │ Int64 Int64 Int64
─────┼─────────────────────
   1 │ -35 -3 6
   2 │ 41 1 -6
   3 │ 34 -3 -7
   4 │ 13 2 9
   5 │ -48 5 2
   6 │ 43 -2 4
   7 │ 38 3 4
   8 │ -12 0 -9
   9 │ -45 3 -1
  10 │ 4 -1 8

julia> Tables.columntable(combine(df,Cols(:).=>mean))
(x_mean = [3.3], y_mean = [0.5], z_mean = [1.0])

julia> copy(combine(df,Cols(:).=>mean)[1,:])
(x_mean = 3.3, y_mean = 0.5, z_mean = 1.0)

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 5, 2022, 7:54pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/5 "2022-05-05T19:54:04Z")

</div>

This is almost never a good idea, and it will only work in global scope. In local scope, this code will start creating global variables.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [May 5, 2022, 8:50pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/6 "2022-05-05T20:50:07Z")

</div>

One could also use named tuples:

```julia
x, y, z = rand(3), rand(3), rand(3)
dmean = map(mean, (;x, y, z))

# and then access the results with:
dmean.x, dmean.y, dmean.z

```

**NB:**  
Learned this from the excellent book in progress: [Julia for Data Analysis, by Bogumił Kamiński](https://www.manning.com/books/julia-for-data-analysis)

---

<div class="post-metadata">

**Author:** ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)\
**Post date:** [June 30, 2022, 7:10pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/7 "2022-06-30T19:10:07Z")

</div>

So what would be a good idea?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 30, 2022, 7:35pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/8 "2022-06-30T19:35:30Z")

</div>

> [@GunnarFarneback](#):
>
> You can do it with `@eval`:

Isn’t this one of those cases where the right answer is: “Don’t do it.” Or maybe “Don’t do this, but if you _must_ know here’s a way”? (Personally, I’m a big fan of telling people their question is wrong, rather than providing an answer 😆 )

> [@roi.holtzman](#):
>
> So what would be a good idea?

Use a `Dict` or maybe a `Vector`. Don’t dynamically create variable names, it makes your code unreadable.

---

<div class="post-metadata">

**Author:** ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)\
**Post date:** [June 30, 2022, 7:47pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/9 "2022-06-30T19:47:28Z")

</div>

But actually, naming the variables does make my code readable, in my opinion.

I mean, I want to save some moments of some variables, `x, y, z`.  
I have a vector named `x` of size, say, 4, to keep all its moments.  
I have the same for `y` and `z`.  
Now, I want to take the new observables I measure stored in `x_tmp, y_tmp, z_tmp`, and put them into `x, y, z`.

I thought about doing something like this.  
Do you think it is more readable to type the entire thing?

```julia
x = zeros(4)
y = zeros(4)
z = zeros(4)

x_tmp = 1
y_tmp = 2
z_tmp = 3

for a in [:x, :y, :z]
  for i = 1:
    eval(a)[i] += eval(Symbol(a, '_', "tmp"))^i
  end
end

```

I must say that I do think I have an issue with the scope of variables, and therefore the way I am doing it now is not good. But I would like to save some on typing the same thing over and over.

Perhaps the best way is to dedicate a function for it.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [June 30, 2022, 8:12pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/10 "2022-06-30T20:12:38Z")

</div>

> [@DNF](#):
>
> Isn’t this one of those cases where the right answer is: “Don’t do it.” Or maybe “Don’t do this, but if you _must_ know here’s a way”? (Personally, I’m a big fan of telling people their question is wrong, rather than providing an answer 😆 )

I thought I kinda said that with

> Most of the time this is not a great idea though and you would be better off organizing your data differently, but it depends on how you are using it.

below the example.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 30, 2022, 8:36pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/11 "2022-06-30T20:36:03Z")

</div>

> [@roi.holtzman](#):
>
> Do you think it is more readable to type the entire thing?

When you write your code like this, you are implying that the individual variable names aren’t that important, you just loop over a list of the names. But there are already data structures for this. You can do

```julia
X = [zeros(4) for _ in 1:3]
tmp = [1, 2, 3]
for i in eachindex(X, tmp)
    X[i] .+= tmp[i]
end

```

or

```julia
X = Dict(:x => zeros(4), :y => zeros(4), :z => zeros(4))
tmp = Dict(:x => 1, :y => 2, :z => 3)
for (key, val) in tmp
    X[key] .+= val
end

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 30, 2022, 8:39pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/12 "2022-06-30T20:39:04Z")

</div>

> [@GunnarFarneback](#):
>
> I thought I kinda said that

Yeah, I must have missed it. I was perhaps expecting a big red “DON’T”.

---

<div class="post-metadata">

**Author:** ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)\
**Post date:** [June 30, 2022, 8:52pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/13 "2022-06-30T20:52:30Z")

</div>

Actually, the names do have a meaning. Therefore, it is actually much more readable to use the names.

In your way of writing, the meaning goes away, and one cannot know what is the 1st, 2nd, and 3rd elements.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 30, 2022, 9:04pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/14 "2022-06-30T21:04:54Z")

</div>

Well, the meaning is also lost (or at least obscured) when you are using eval:

```julia
eval(a)[i] += eval(Symbol(a, '_', "tmp"))^i

```

> [@roi.holtzman](#):
>
> In your way of writing, the meaning goes away, and one cannot know what is the 1st, 2nd, and 3rd elements.

There’s no clear ordering with just names, “x”, “y” and “z” (you may perhaps infer it from the alphabet), so the ordering is much clearer if you use an array, because then you have indices 1, 2, and 3.

If the names have significant meaning, you can keep them using a `Dict`. I don’t see how there is more ordering in variable names than in the same names as field names in a Dict.

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [June 30, 2022, 9:42pm UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/15 "2022-06-30T21:42:02Z")

</div>

> [@DNF](#):
>
> can keep them using a `Dict`

^^this^^, and structs encapsulating related derived values. Organize your data. Don’t pollute your namespace. struct fields have names, so that naming can be preserved.

---

<div class="post-metadata">

**Author:** ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)\
**Post date:** [July 1, 2022, 7:55am UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/16 "2022-07-01T07:55:13Z")

</div>

First, let me take a more concrete example: say the first array is position, `x`, the second is velocity `v`, and the third is acceleration `a`. Now, these have a clear meaning.

From what I understand, you suggest I would keep my arrays in a `dict`.  
Is there a better way to initiate it than this? (and later on to fill it?)  
I mean using a for loop or something.  
(Consider the case I have O(10) of these quantities).

```julia
d = Dict()
d["x"] = zeros(4)
d["v"] = zeros(4)
d["a"] = zeros(4)

```

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [July 1, 2022, 8:02am UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/17 "2022-07-01T08:02:10Z")

</div>

```julia
julia> Dict(["x", "v", "a"] .=> [zeros(4) for _ ∈ 1:3])
Dict{String, Vector{Float64}} with 3 entries:
  "v" => [0.0, 0.0, 0.0, 0.0]
  "x" => [0.0, 0.0, 0.0, 0.0]
  "a" => [0.0, 0.0, 0.0, 0.0]

```

Will give you a correctly typed dictionary (yours is `Dict{Any, Any}`)

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [July 1, 2022, 8:50am UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/18 "2022-07-01T08:50:27Z")

</div>

That construction looks somewhat contrived. I would write it as

```julia
Dict(key => zeros(4) for key in ["x", "v", "a"])

```

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [July 1, 2022, 8:55am UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/19 "2022-07-01T08:55:33Z")

</div>

Ah yes, much nicer - not necessary to construct an array on the right hand side.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 1, 2022, 9:55am UTC](https://discourse.julialang.org/t/looping-over-variables-names-properly/80468/20 "2022-07-01T09:55:06Z")

</div>

> [@roi.holtzman](#):
>
> First, let me take a more concrete example: say the first array is position, `x`, the second is velocity `v`, and the third is acceleration `a`. Now, these have a clear meaning.

Thanks for making it more concrete.

If you are bundling together position, velocity and acceleration, presumably for some body, then I think you should consider creating a type (possibly `mutable`, depending on need):

```julia
struct Particle
    x::T
    v::T
    a::T
end

```

with whichever type `T` is useful for you (apparently a length-4 vector?) Then you can make arrays of `Particles`, if you need that.

> [@roi.holtzman](#):
>
> (Consider the case I have O(10) of these quantities).

What does O(10) mean? Perhaps even some more concrete background would be useful.

> [@roi.holtzman](#):
>
> `d["x"] = zeros(4)`

If you were to use `Dict`, I think using symbols is perhaps more appropriate: `d[:x] = zeros(4)`
