# Unexpected behaviour in nested DefaultDicts

**URL:** <https://discourse.julialang.org/t/unexpected-behaviour-in-nested-defaultdicts/29440>\
**Category:** New to Julia\
**Created:** [October 3, 2019, 10:06am UTC](https://discourse.julialang.org/t/unexpected-behaviour-in-nested-defaultdicts/29440 "2019-10-03T10:06:01Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![PaulMainwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulmainwood/32/9578_2.png) [@PaulMainwood](https://discourse.julialang.org/u/PaulMainwood)\
**Post date:** [October 3, 2019, 10:06am UTC](https://discourse.julialang.org/t/unexpected-behaviour-in-nested-defaultdicts/29440/1 "2019-10-03T10:06:02Z")

</div>

I am using a structure where I want to use nested DefaultDicts. The outer one, I want to default to an empty DefaultDict, which in turn I want to have a default value of 1.0.

```julia
julia> d = DefaultDict{Int64, DefaultDict}(DefaultDict{Int64, Float64}(1.0))
DefaultDict{Int64,DefaultDict,DefaultDict{Int64,Float64,Float64}} with 0 entries

julia> d[1][1]
1.0

julia> d[1][1] = 4.0
4.0

julia> d[1][3]
1.0

julia> d[6][1]
4.0

```

I was not expecting the last result (which of course comes out the same whatever the value of the outer Dict index). I was expecting the outer DefaultDict to produce a new, empty inner DefaultDict and so default back to a 1.0. Instead, it seems to be using the existing inner DefaultDict as the new default for any new outer one.

Can you help me understand this and how to achieve my expected behaviour?

(I am new to Julia, and to programming in general, so if you think the issue is too blindingly obvious to need saying, please say it anyway.)

---

<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 3, 2019, 10:59am UTC](https://discourse.julialang.org/t/unexpected-behaviour-in-nested-defaultdicts/29440/2 "2019-10-03T10:59:50Z")

</div>

So what is happening is that

```julia
outer = DefaultDict{Int64, DefaultDict}(DefaultDict{Int64, Float64}(1.0))

```

is the same as:

```julia
inner = DefaultDict{Int64, Float64}(1.0)
outer = DefaultDict{Int64, DefaultDict}(inner)

```

So whenever `outer` needs a default value,  
it returns `inner`.  
Not a copy of inner, or a new `DefaultDict` equal to `inner`, but actually `inner` itself.  
Which means that mutating that returned value, is literally mutating `inner`.

* * *

If rather than passing in a value, you pass in a function (or a constructor) as the default,  
then DefaultDict will invoke that function and return the value.  
You can use this to make it construct a new inner dict each time it wants one.

```julia
julia> construct_new_inner() = DefaultDict{Int64, Float64}(1.0);

julia> outer = DefaultDict{Int64, DefaultDict}(construct_new_inner)
DefaultDict{Int64,DefaultDict,var"##9#10"} with 0 entries

julia> outer[1][1]
1.0

julia> outer[1][1] = 4.0
4.0

julia> outer[1][3]
1.0

julia> outer[6][1]
1.0

```

Which can also be written as:

```julia
d = DefaultDict{Int64, DefaultDict}(()->DefaultDict{Int64, Float64}(1.0))

```
