# 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:** 1\
**Showing post:** 2

<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))

```

---

_[View the full topic](https://discourse.julialang.org/t/unexpected-behaviour-in-nested-defaultdicts/29440)._
