# How do I append/add data in dictionary with same key?

**URL:** <https://discourse.julialang.org/t/how-do-i-append-add-data-in-dictionary-with-same-key/15891>\
**Category:** New to Julia\
**Created:** [October 4, 2018, 5:15pm UTC](https://discourse.julialang.org/t/how-do-i-append-add-data-in-dictionary-with-same-key/15891 "2018-10-04T17:15:38Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Elmer\_Cusipuma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elmer_cusipuma/32/11958_2.png) [@Elmer\_Cusipuma](https://discourse.julialang.org/u/Elmer_Cusipuma)\
**Post date:** [October 4, 2018, 5:15pm UTC](https://discourse.julialang.org/t/how-do-i-append-add-data-in-dictionary-with-same-key/15891/1 "2018-10-04T17:15:38Z")

</div>

I am trying create a Dictionary from array

```julia
data = ["COMB1" 1.4;
        "COMB2" 1.2;
        "COMB2" 1.6;
        "COMB3" 1.2;
        "COMB3" 1.4;
        "COMB3" 1.3;
        "COMB3" 1.5];

```

I tried to do that by the following command

`dict = Dict( data[i,1] => data[i,2] for i=1:size(data,1))`

the output is:

```julia
Dict String → Float64 with 3 entries
"COMB1" → 1.40
"COMB2" → 1.60
"COMB3" → 1.50

```

I was expecting is something like:

```julia
Dict("COMB1" => 1.4,
     "COMB2" => [1.2,1.6],
     "COMB3" => [1.2,1.4,1.3,1.5]);

Dict String → Any with 3 entries
"COMB1" → 1.40
"COMB2" → Float64[2]
"COMB3" → Float64[4]

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [October 4, 2018, 5:43pm UTC](https://discourse.julialang.org/t/how-do-i-append-add-data-in-dictionary-with-same-key/15891/2 "2018-10-04T17:43:17Z")

</div>

A dictionary is a mapping from a key to a single value (the value could be an array). If you set an existing key to a new value, the previous value will be overwritten.

So create a dictionary where each value is a vector, and `push!` values to that vector instead.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [October 4, 2018, 6:03pm UTC](https://discourse.julialang.org/t/how-do-i-append-add-data-in-dictionary-with-same-key/15891/3 "2018-10-04T18:03:46Z")

</div>

I’m not sure if the context, but this is just the sort of aggregation operation that dataframes are designed for.

One option is to do

```julia
using DataFrames

df = DataFrame(dict)
dict = Dict{String,Vector{Float64}}()
by(sdf -> (dict[sdf[1,:x1]] = sdf.x2), df, :x1)

```

which is either overly elaborate or perfectly reasonable depending on the context.

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [October 5, 2018, 1:26am UTC](https://discourse.julialang.org/t/how-do-i-append-add-data-in-dictionary-with-same-key/15891/4 "2018-10-05T01:26:27Z")

</div>

I’ll just mention that the solution proposed by Kristoffer Carlsson is, as far as I know, the solution everyone uses, but it has a performance hit under the hood because you need to write code like:

```julia
  if !haskey(d, k)
     d[k] = [v]
  else
     push!(d[k],v)
  end

```

so in other words, the same key needs to be looked up multiple times. It would be better to somehow remember the position in the dictionary. This is the subject of an open issue that has not been resolved:

[https://github.com/JuliaLang/julia/issues/24454](https://github.com/JuliaLang/julia/issues/24454)

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [October 5, 2018, 2:52am UTC](https://discourse.julialang.org/t/how-do-i-append-add-data-in-dictionary-with-same-key/15891/5 "2018-10-05T02:52:00Z")

</div>

I use either `get!` or a `DefaultDict` for this.  
Either way it avoids the double lookup @Stephen_Vavasis was unhappy about.

### `get!` tries to find an element and if one is not found calls the function insterting that as the element

```julia-auto
dict = Dict{String, Vector{Float64}}()
for i in 1:size(data,1)
	(kk, vv) = data[i,:]
	vals = get!(Vector{Float64}, dict, kk)
	push!(vals, vv)
end

```

Output

```julia-auto
julia> @show dict
dict = Dict("COMB1"=>[1.4],"COMB2"=>[1.2, 1.6],"COMB3"=>[1.2, 1.4, 1.3, 1.5])
Dict{String,Array{Float64,1}} with 3 entries:
  "COMB1" => [1.4]
  "COMB2" => [1.2, 1.6]
  "COMB3" => [1.2, 1.4, 1.3, 1.5]

```

### DataStructures defaultdict

```julia-auto
dict = DefaultDict{String,Vector{Float64}}(Vector{Float64})

for i in 1:size(data,1)
	(kk, vv) = data[i,:]
	push!(dict[kk], vv)
end

```

output

```julia-auto
julia> @show dict
dict = DefaultDict("COMB1"=>[1.4],"COMB2"=>[1.2, 1.6],"COMB3"=>[1.2, 1.4, 1.3, 1.5])
DefaultDict{String,Array{Float64,1},DataType} with 3 entries:
  "COMB1" => [1.4]
  "COMB2" => [1.2, 1.6]
  "COMB3" => [1.2, 1.4, 1.3, 1.5]

```

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [October 5, 2018, 3:13am UTC](https://discourse.julialang.org/t/how-do-i-append-add-data-in-dictionary-with-same-key/15891/6 "2018-10-05T03:13:22Z")

</div>

You are right – this solves the OP’s problem. When the ‘value’ is mutable and needs mutating, your post shows how to avoid the double-lookup. So the open issue I referred to above applies only when the value is of an immutable type (or a mutable type that needs to overwritten rather than mutated).
