# Looking for a key in a nested dict

**URL:** https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211
**Category:** New to Julia
**Created:** [November 6, 2018, 11:21am UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211 "2018-11-06T11:21:00Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)
#### Post date: [November 6, 2018, 11:21am UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/1 "2018-11-06T11:21:00Z")

</div>

Hello everyone,

I’m trying to search for a specific key in a deeply nested dict which can also contain arrays.  
In a first step I import a yaml file which I parse using YAML.jl. This gives me a nested dict.  
If we take the truncated example of the README file from the YAML.jl package:

```julia
# data.yml
receipt: Oz-Ware Purchase Invoice
date: 2012-08-06
customer:
    given: Dorothy
    family: Gale

```

This would be parsed as

```julia
julia> using YAML

julia> data = YAML.load(open("data.yml"))
Dict{Any,Any} with 3 entries:
  "receipt" => "Oz-Ware Purchase Invoice"
  "customer" => Dict{Any,Any}(Pair{Any,Any}("given", "Dorothy"),Pair{Any,Any}("…
  "date" => 2012-08-06

```

How would I access in for instance the value of the “given” form the dict corresponding to “customer”?  
I would like to achieve this in a general way, where there could be multiple levels of nesting.

I tried to translate the following python code which I found on [StackExchange](https://codereview.stackexchange.com/questions/201754/getting-a-keys-value-in-a-nested-dictionary):

```julia
def retrieve_nested_value(mapping, key_of_interest):
    mappings = [mapping]
    while mappings:
        mapping = mappings.pop()
        try:
            items = mapping.items()
        except AttributeError:
            # we didn't store a mapping earlier on so just skip that value
            continue

        for key, value in items:
            if key == key_of_interest:
                yield value
            else:
                # type of the value will be checked in the next loop
                mappings.append(value)

```

where `mapping` is a dict.

This is my attempt to translate it to julia

```julia
function retreive_nested_value(dict, key_of_interest)
    dictv = [dict]
    while isempty(dictv) == false
        dict = pop!(dictv)
        for (key,value) in dict
            if key == key_of_interest
                return value
            else
                dictv = [dictv , [value]]
            end
        end
    end
end

```

But unfortunately, it gives me only the values of the first level (same as get(dict, key\_of\_interest,0)). I cannot fetch the values of the lower levels.

How would one do this in julia?  
Many thanks in advance,  
Olivier

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [November 6, 2018, 1:16pm UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/2 "2018-11-06T13:16:51Z")

</div>

Wouldn’t this be a classic case of recursion? This code can be easily modified to push multiple positive results to an array.

```julia
function retrieve(dict, key_of_interest)
        for (key, value) in dict
        if key == key_of_interest
        	return value
        end
        if value isa Dict
            return retrieve(value, key_of_interest)
        end
    end
end

```

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [November 6, 2018, 1:21pm UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/3 "2018-11-06T13:21:59Z")

</div>

Nice, could possibly also descend into any `AbstractDict`.

---

<div class="post-metadata">

### Author: ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)
#### Post date: [November 6, 2018, 1:27pm UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/4 "2018-11-06T13:27:59Z")

</div>

Thanks a lot for looking into this,

Unfortunately, the code does not return anything.  
Should I do something extra to get the values?  
I tried on both julia 0.6.4 and 0.7

Could you do it without recursion?

Thanks again

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [November 6, 2018, 1:31pm UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/5 "2018-11-06T13:31:16Z")

</div>

It definitely returns something, provided the key is the Dict somewhere. Could you give a minimum working example? Recursion is definitely the default way to solve these kinds of problems.

---

<div class="post-metadata">

### Author: ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)
#### Post date: [November 6, 2018, 2:11pm UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/7 "2018-11-06T14:11:34Z")

</div>

> t definitely returns something, provided the key is the Dict somewhere.

Yes indeed. My bad. It works fine when the key occurs only once.  
If it occurs multiple times, then nothing is returned.

I’m trying now to add multiple occurrences into an array as you said.

Thanks again!

---

<div class="post-metadata">

### Author: ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)
#### Post date: [November 6, 2018, 2:12pm UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/8 "2018-11-06T14:12:32Z")

</div>

I’m not sure I understand what you mean.  
Could you expand a little?

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [November 6, 2018, 2:16pm UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/9 "2018-11-06T14:16:50Z")

</div>

If it ocurs multiple times, only the first appearance of the key is returned. Here is an implementation that takes into account multiple returns

```julia
function retrieve(dict, key_of_interest, output = []) # default value is an empty array
               for (key, value) in dict
               if key == key_of_interest
                       push!(output, value)
               end
               if value isa AbstractDict
                   retrieve(value, key_of_interest, output)
               end
           end
           return output
       end

```

---

<div class="post-metadata">

### Author: ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)
#### Post date: [November 6, 2018, 2:27pm UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/10 "2018-11-06T14:27:59Z")

</div>

ok, great!

I just managed a similar solution, but yours is much more elegant.  
Here is mine:

```julia
function retrieve2(dict, key_of_interest)
    values = Vector{Any}()
    for (key, value) in dict
        if key == key_of_interest
            append!(values,[value])
        end
        if value isa Dict
            val = retrieve(value, key_of_interest)
        append!(values,val)
        end
     end
     return values   
end

```

Thanks again to all of you!

---

<div class="post-metadata">

### Author: ![system](https://global.discourse-cdn.com/julialang/original/3X/1/2/12829a7ba92b924d4ce81099cbf99785bee9b405.png) [@system](https://discourse.julialang.org/u/system)
#### Post date: [November 18, 2018, 2:28pm UTC](https://discourse.julialang.org/t/looking-for-a-key-in-a-nested-dict/17211/11 "2018-11-18T14:28:01Z")

</div>

This topic was automatically closed 12 days after the last reply. New replies are no longer allowed.
