# Initialize a Dict by broadcasting

**URL:** <https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810>\
**Category:** New to Julia\
**Tags:** question, dictionary, arrays, broadcasting\
**Created:** [November 5, 2022, 12:36pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810 "2022-11-05T12:36:00Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![healyp](https://avatars.discourse-cdn.com/v4/letter/h/67e7ee/32.png) [@healyp](https://discourse.julialang.org/u/healyp)\
**Post date:** [November 5, 2022, 12:36pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/1 "2022-11-05T12:36:00Z")

</div>

I’d like to initialise a dictionary of type `Dict{Date, Vector{Float64}}` . Clearly, I can do

```julia
Dict(d => Vector{Float64}() for d in mydates)

```

but can I do it by broadcasting? I have tried

```julia
Dict(mydates .=> Vector{Float64}[]) # Vector{Float64}() also fails

```

but this returns a `DimensionMismatch` error.

Many thanks.

---

<div class="post-metadata">

**Author:** ![cgeoga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cgeoga/32/216186_2.png) [@cgeoga](https://discourse.julialang.org/u/cgeoga)\
**Post date:** [November 5, 2022, 12:59pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/2 "2022-11-05T12:59:33Z")

</div>

If `mydates` isn’t empty, then the broadcast you’re asking for doesn’t really make sense because one side is an empty container. There are plenty of ways to instantiate a `Vector` of `Vector{Float64}`, but one possible way that I think illustrates the source of the error is

```julia
Dict(mydates .=> [Vector{Float64}() for _ in 1:length(mydates)])

```

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [November 5, 2022, 1:04pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/3 "2022-11-05T13:04:16Z")

</div>

> [@healyp](#):
>
> `Dict(d => Vector{Float64}() for d in mydates)`

or

```julia
Dict(d => Float64[] for d in mydates)

```

is the best you can do.

The reason is:

1. it is readable.
2. it is correct.

The point about correctness is that you need to make sure that you allocate a fresh vector for each dictionary entry, and this is what comprehension does (that is why in the solution by @cgeoga also a comprehension had to be used)

You most likely wanted to write something like:

```julia
Dict(mydates .=> Ref(Vector{Float64}()))

```

unfortunately this would not be correct as dictionary values would be aliases.

---

<div class="post-metadata">

**Author:** ![healyp](https://avatars.discourse-cdn.com/v4/letter/h/67e7ee/32.png) [@healyp](https://discourse.julialang.org/u/healyp)\
**Post date:** [November 5, 2022, 1:58pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/5 "2022-11-05T13:58:26Z")

</div>

This would have been my understanding, too, up until I saw that (in a different context) I could do

```julia
Dict(mydates .=> 0)

```

or even

```julia
Dict(mydates .=> "this is a string of not inconsiderable length")

```

Is something akin to a constructor not being called in order to make multiple copies of the string?

Thanks for your patience.

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [November 5, 2022, 2:45pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/6 "2022-11-05T14:45:36Z")

</div>

> [@healyp](#):
>
> Is something akin to a constructor not being called in order to make multiple copies of the string?

String is immutable, so it does not have to be copied. It is not a problem to reuse it. Same with `0`.

Also note that this works as numbers and strings are considered as 0-dimensional containers by broadcasting, so you do not have to wrap them in `Ref`.

---

<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:** [November 5, 2022, 2:49pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/7 "2022-11-05T14:49:59Z")

</div>

> [@bkamins](#):
>
> You most likely wanted to write something like:
> 
> ```julia
> Dict(mydates .=> Ref(Vector{Float64}[]))
> 
> ```
> 
> unfortunately this would not be correct as dictionary values would be aliases.

Shouldn’t it be `d = Dict (mydates. => Ref (Float64 []))` instead?  
Can you explain in more detail, perhaps with examples, this fact: “as dictionary values would be aliases.”?

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [November 5, 2022, 3:02pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/8 "2022-11-05T15:02:46Z")

</div>

It was a typo, as I was copy-pasting from both solutions. Fixed.

An example of aliasing consequences:

```julia
julia> d = Dict(1:2 .=> Ref(Float64[]))
Dict{Int64, Vector{Float64}} with 2 entries:
  2 => []
  1 => []

julia> d[1] === d[2]
true

julia> push!(d[1], 100)
1-element Vector{Float64}:
 100.0

julia> d
Dict{Int64, Vector{Float64}} with 2 entries:
  2 => [100.0]
  1 => [100.0]

```

---

<div class="post-metadata">

**Author:** ![cgeoga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cgeoga/32/216186_2.png) [@cgeoga](https://discourse.julialang.org/u/cgeoga)\
**Post date:** [November 5, 2022, 3:11pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/9 "2022-11-05T15:11:30Z")

</div>

To be clear also, this isn’t just a feature of `Ref`. The [docs on broadcasting](https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting) comment on this: wrapping elements in a container changes the way that broadcasting works. So this also has the same issue:

```julia
julia> x = rand(5);

julia> t = Float64[];

julia> d = Dict(x .=> [t]);

julia> push!(t, 1.0)
1-element Vector{Float64}:
 1.0

julia> d
Dict{Float64, Vector{Float64}} with 5 entries:
  0.251673 => [1.0]
  0.877861 => [1.0]
  0.766795 => [1.0]
  0.814601 => [1.0]
  0.733239 => [1.0]

```

Note that if you just tried to make `Dict(x .=> t)` before `push!`-ing to it, you’d get your error. But after `push!`-ing, you get this:

```julia
julia> Dict(x .=> t)
Dict{Float64, Float64} with 5 entries:
  0.336598 => 1.0
  0.506931 => 1.0
  0.0600524 => 1.0
  0.874898 => 1.0
  0.711234 => 1.0

```

But look at the types—it isn’t a `Dict{Float64, Vector{Float64}}` anymore!

To see that this is a special case of singleton containers, here’s one more demo:

```julia
push!(t, 2.0);
Dict(x .=> t) # Error: DimensionMismatch: [...]

```

So the way that broadcasting works here is actually a bit subtle.

EDIT: I’ve tried to be pretty focused on actually answering your question about broadcasting, but to be clear and for what it’s worth, I think @bkamins advice is best and that broadcasting just seems like a bit of a footgun here. That’s not how I’d choose to construct a `Dict` like this. But then, it’s your code and your use case and stuff, so take that for whatever it’s worth.

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [November 5, 2022, 3:13pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/10 "2022-11-05T15:13:55Z")

</div>

> [@cgeoga](#):
>
> To be clear also, this isn’t just a feature of `Ref`

Yes, there is nothing special about `Ref`. `Ref` is just a container (it is typically used in such cases as it has least impact on [`BroadcastStyle`](https://docs.julialang.org/en/v1/manual/interfaces/#Broadcast-Styles)).

---

<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:** [November 5, 2022, 3:24pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/11 "2022-11-05T15:24:19Z")

</div>

if instead of the `push! ()` function you use `setindex!()` this problem is avoided or are there potentially other unwanted effects?

```julia
d[Date("2022-04-02")]=[1.,2.]
d[Date("2022-04-30")]=[10.,20.]
julia> push!(d[Date("2022-04-30")],30.)
3-element Vector{Float64}:
 10.0
 20.0
 30.0

julia> d
Dict{Date, Vector{Float64}} with 40 entries:
  Date("2022-04-02") => [1.0, 2.0]
  Date("2022-04-30") => [10.0, 20.0, 30.0]
  Date("2022-01-15") => []
...
julia> push!(d[Date("2022-04-23")],30.)
1-element Vector{Float64}:
 30.0

julia> d
Dict{Date, Vector{Float64}} with 40 entries:
  Date("2022-04-02") => [1.0, 2.0]
  Date("2022-04-30") => [10.0, 20.0, 30.0]
  Date("2022-01-15") => [30.0]
  Date("2022-10-01") => [30.0]
  Date("2022-07-02") => [30.0]
....

```

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [November 5, 2022, 3:58pm UTC](https://discourse.julialang.org/t/initialize-a-dict-by-broadcasting/89810/12 "2022-11-05T15:58:15Z")

</div>

If vectors are aliases then both `setindex!` and `push!` will be problematic.
