# Best way of building a heavily nested Dict

**URL:** https://discourse.julialang.org/t/best-way-of-building-a-heavily-nested-dict/14139
**Category:** General Usage
**Created:** [August 27, 2018, 3:09pm UTC](https://discourse.julialang.org/t/best-way-of-building-a-heavily-nested-dict/14139 "2018-08-27T15:09:30Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)
#### Post date: [August 27, 2018, 3:09pm UTC](https://discourse.julialang.org/t/best-way-of-building-a-heavily-nested-dict/14139/1 "2018-08-27T15:09:30Z")

</div>

I want to create a nested Dict from a list of data. I think it’s clear from this non-working example what I want to do:

```julia
# make dummy data
n = 1000
r = [rand(string.('A':'Z'), n, 5) rand(n,1)]

# build a nested Dict
nested = Dict() # or Dict(Dict(Dict(...))) or whatever
for i=1:n
    a,b,c,d,e = r[i,1:5]
    nested[a][b][c][d][e] = r[i,6]
end

```

What is the most compact and elegant way of building this structure without creating key combinations not in the list, and without descending too far into `haskey()` hell? Extra brownie points if the Dicts are correctly typed instead of using Any.

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [August 27, 2018, 5:18pm UTC](https://discourse.julialang.org/t/best-way-of-building-a-heavily-nested-dict/14139/2 "2018-08-27T17:18:20Z")

</div>

It rather depends on how you want your data in memory. For example, you could flatten this all into one Dict, by using `(a, b, c, d, e)` as the key, but then you lose the ability to enumerate or count the subsets easily.

For building this, without lots of `haskey` calls, you can use a mutating get call:

```julia
get!(..., get!(Dict{...}, get!(Dict{Dict{...}}, get!(Dict{Dict{Dict{...}}},
    nested, a), b), c), d)[e] = r[i, 6]

```

(although you might want to use simply `Dict{String, Any}` for each of those constructors, but ymmv)

---

<div class="post-metadata">

### Author: ![tshort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tshort/32/43_2.png) [@tshort](https://discourse.julialang.org/u/tshort)
#### Post date: [August 27, 2018, 6:46pm UTC](https://discourse.julialang.org/t/best-way-of-building-a-heavily-nested-dict/14139/3 "2018-08-27T18:46:05Z")

</div>

[IndexedTables](https://github.com/JuliaComputing/IndexedTables.jl) is another option.

---

<div class="post-metadata">

### Author: ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)
#### Post date: [August 27, 2018, 7:08pm UTC](https://discourse.julialang.org/t/best-way-of-building-a-heavily-nested-dict/14139/4 "2018-08-27T19:08:34Z")

</div>

Yes, in particular [NDSparse](https://juliadb.org/latest/api/datastructures.html#NDSparse-1).

---

<div class="post-metadata">

### Author: ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)
#### Post date: [August 27, 2018, 7:49pm UTC](https://discourse.julialang.org/t/best-way-of-building-a-heavily-nested-dict/14139/5 "2018-08-27T19:49:00Z")

</div>

Thanks! Let me just fill in the dots in your proposal in case anyone else is wondering:

```julia
nested = Dict()
for i=1:n
    a,b,c,d,e = r[i,1:5]
    get!(Dict, get!(Dict, get!(Dict, get!(Dict, nested, a), b), c), d)[e] = r[i, 6]
end

```

That will make nested dicts of type `Dict{Any,Any}`. To get more specific types, i.e. `Dict{String, Dict{String, ...}}` with an inner `Float64`, something like this would work:

```julia
dict(n) = n == 0 ? Float64 : Dict{String, dict(n-1)}
nested = dict(5)()
for i=1:n
    a,b,c,d,e = r[i,1:5]
    get!(dict(1), get!(dict(2), get!(dict(3), get!(dict(4), nested, a), b), c), d)[e] = r[i, 6]
end

```

I’m sure it’s possible to make the `get!()` calls recursive as well, but I don’t have time to work out the details right now.

I was shooting for a nested Dict implementation since I’m going to have the same datastructure in Julia and Javascript, and Javascript can’t do anything fancier than nested objects. So sadly I think flattened Dicts or IndexedTables are off the table. Thanks for the suggestions though.
