Is it possible to automate this:

```
#I currently have:
y_TX, m_TX, ŷ_TX, ATT_TX, ATT_co, se_i_TX, se_t_TX = [], [], [], [], [], [], []
# I want something like:
y_TX, m_TX, ŷ_TX, ATT_TX, ATT_co, se_i_TX, se_t_TX = []
```

Is it possible to automate this:

```
#I currently have:
y_TX, m_TX, ŷ_TX, ATT_TX, ATT_co, se_i_TX, se_t_TX = [], [], [], [], [], [], []
# I want something like:
y_TX, m_TX, ŷ_TX, ATT_TX, ATT_co, se_i_TX, se_t_TX = []
```

1 Like

You can do:

```
y_TX, m_TX, ŷ_TX, ATT_TX, ATT_co, se_i_TX, se_t_TX = ntuple(_ -> [], 7)
```

8 Likes

You can do something like

```
a, b, c = ([] for _ in 1:3)
```

Be careful, because that way the arrays are of type Any, thus inefficient.

3 Likes

Thanks but I keep adding new variables as I write, is it possible to do something like

```
a, b, c = ([] for _ in 1:end)
```

1 Like

You could just pick a really big upper bound, only the elements of the iterator you actually use will be created:

```
a, b, c = ([] for _ in 1:1000)
a, b, c, d = ([] for _ in 1:1000)
a, b, c, d, e = ([] for _ in 1:1000)
# etc...
```

6 Likes

Could use `Iterators.repeated`

here:

```
julia> using .Iterators: repeated
julia> a, b, c = repeated([]);
julia> a
Any[]
julia> b
Any[]
julia> c
Any[]
```

2 Likes

That just repeats the same object though, using the comprehension makes independent `[]`

's.

7 Likes

```
julia> using .Iterators: repeated
julia> a, b, c = repeated([]);
julia> push!(a, 2)
1-element Array{Any,1}:
2
julia> b
1-element Array{Any,1}:
2
```

3 Likes

If you do not mind a new struct type:

```
struct OnRepeat{F}
f :: F
end
function Base.iterate(o :: OnRepeat{F}, s :: Nothing = nothing) where {F}
return o.f(), nothing
end
a, b, c = OnRepeat(() -> [])
```

And now you can use `OnRepeat`

with any function taking no arguments and returning the new object you want.

7 Likes

good catch!

1 Like

I’ve sometimes defined a macro to help with this exact scenario,

```
macro repeated(x)
:(($(esc(x))) for _ in Iterators.repeated(nothing))
end
```

then you can do

```
a, b, c = @repeated([])
```

I think I even proposed adding this to Base.Iterators but there were some valid concerns which I forget the details of now though.

5 Likes

could also just do

```
copy_repeated(x) = (copy(x) for x in Iterators.repeated(x))
```

then

```
julia> a, b, c = copy_repeated([])
Base.Generator{Base.Iterators.Repeated{Vector{Any}}, typeof(copy)}(copy, Base.Iterators.Repeated{Vector{Any}}(Any[]))
julia> push!(a, 1)
1-element Vector{Any}:
1
julia> b
Any[]
```

(or `Iterators.map(copy, repeated(x))`

if you’re on 1.6+

6 Likes

There are some issues w/ some of the methods proposed above.

**Method 1**:

```
julia> zs = zeros(3)
3-element Vector{Float64}:
0.0
0.0
0.0
julia> a, b, c = (zs for _ in 1:100)
Base.Generator{UnitRange{Int64}, var"#33#34"}(var"#33#34"(), 1:100)
julia> a, b, c, zs
([0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])
julia> b = ones(3)
3-element Vector{Float64}:
1.0
1.0
1.0
julia> a, b, c, zs # only b is changed
([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])
julia> a[1:2] = ones(2)
2-element Vector{Float64}:
1.0
1.0
julia> a, b, c, zs # a, c, zs are changed, but not b. Why?
([1.0, 1.0, 0.0], [1.0, 1.0, 1.0], [1.0, 1.0, 0.0], [1.0, 1.0, 0.0])
```

When I change `b`

to a new vector, only b is changed, while `a, c, zs`

are unchanged.

When I change *some elements* of `a`

to a new vector, then `a, c, zs`

are all changed in the same way, while `b`

is unchanged.

**Method 2**:

```
julia> copy_repeated(x) = (copy(x) for x in Iterators.repeated(x))
copy_repeated (generic function with 1 method)
julia> zs = zeros(3)
3-element Vector{Float64}:
0.0
0.0
0.0
julia> a, b, c = copy_repeated(zs)
Base.Generator{Base.Iterators.Repeated{Vector{Float64}}, typeof(copy)}(copy, Base.Iterators.Repeated{Vector{Float64}}([0.0, 0.0, 0.0]))
julia> a, b, c, zs
([0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])
julia> b = ones(3)
3-element Vector{Float64}:
1.0
1.0
1.0
julia> a, b, c, zs # only b is changed
([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])
julia> a[1:2] = ones(2)
2-element Vector{Float64}:
1.0
1.0
julia> a, b, c, zs # only a is changed
([1.0, 1.0, 0.0], [1.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])
```

@Mason’s method gives me what I expected.

Q: is the behavior of the 1st method `a, b, c = (zs for _ in 1:100)`

as intended?

Here you assigned `b`

to be a new vector of ones. If you wanted to mutate the vector that was there, you must use ` b .= 1`

, or `b[1] = 1`

, etc.:

```
julia> zs = zeros(3);
julia> a, b, c = (zs for _ in 1:3)
Base.Generator{UnitRange{Int64}, var"#1#2"}(var"#1#2"(), 1:3)
julia> a
3-element Vector{Float64}:
0.0
0.0
0.0
julia> a[1] = 1
1
julia> a,b,c
([1.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 0.0, 0.0])
```

Ah, I see you already noted that. Yes, that is the expected behavior. If you don’t want the vectors to be the same, you need to copy them:

```
julia> a, b, c = (copy(zs) for _ in 1:3)
Base.Generator{UnitRange{Int64}, var"#3#4"}(var"#3#4"(), 1:3)
julia> a
3-element Vector{Float64}:
1.0
0.0
0.0
julia> a[1] = 2
2
julia> a, b, c
([2.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 0.0, 0.0])
```

3 Likes

Yes.

We talked about assignment vs copy here.

I brought this up in case future users come to this thread, so the diff betw the following is clear:

```
a, b, c = (zs for _ in 1:3)
a, b, c = (copy(zs) for _ in 1:3)
a, b, c = (copy(zs) for i in Iterators.repeated(zs))
```

3 Likes