# How to get values of dictionary by using array of keys?

**URL:** <https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650>\
**Category:** General Usage\
**Tags:** dictionary\
**Created:** [December 26, 2021, 4:11pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650 "2021-12-26T16:11:00Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![rmsmsgood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rmsmsgood/32/20544_2.png) [@rmsmsgood](https://discourse.julialang.org/u/rmsmsgood)\
**Post date:** [December 26, 2021, 4:11pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/1 "2021-12-26T16:11:00Z")

</div>

I want access to dictionary with vector, or array. If it possible natively, i want like below code:

```julia
julia> foo = Dict("Ac" => 4, "B" => 1, "d" => 2)
Dict{String, Int64} with 3 entries:
  "B" => 1
  "Ac" => 4
  "d" => 2

julia> bar = ["Ac", "Ac", "d"]
3-element Vector{String}:
 "Ac"
 "Ac"
 "d"

julia> foo[bar]
3-element Vector{Int64}:
 4
 4
 2

```

Of course if `bar` is array of integer, then i can use array of array but i need string index. Is there good solution?

---

<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:** [December 26, 2021, 4:15pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/2 "2021-12-26T16:15:06Z")

</div>

```julia
julia> getindex.(Ref(foo), bar)
3-element Vector{Int64}:
 4
 4
 2

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [December 26, 2021, 6:35pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/3 "2021-12-26T18:35:00Z")

</div>

```julia
get.([foo],bar,"na")

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 26, 2021, 7:50pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/4 "2021-12-26T19:50:32Z")

</div>

@rocco_sprmnt21, returning an integer as default seems to further speed up your solution. Some _type stability_ matter?

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [December 26, 2021, 7:51pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/5 "2021-12-26T19:51:19Z")

</div>

Or

```julia
[foo[i] for i in bar]

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [December 26, 2021, 8:05pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/6 "2021-12-26T20:05:34Z")

</div>

I was looking for an acronym for “not available” value.  
I still don’t quite understand (euphemism) the type stability issues, so I don’t know how to generally take them into account.  
In this case I could use the default “Inf” as an acronym for “index not found” 😃

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [December 26, 2021, 9:26pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/7 "2021-12-26T21:26:02Z")

</div>

Type stability means the function returns the same type every time (or rather the type of the output is entirely determined by the type of the inputs). Returning `Inf` won’t help, you’ll need an `Int`. `-1` or `0` or `typemin(Int)` are typical choices. If those are meaningful values, maybe there is no good integer choice. If so, you can abandon type stability, I would probably go with `missing`.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [December 27, 2021, 12:41pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/8 "2021-12-27T12:41:36Z")

</div>

ah … here’s the problem that _Inf_ is only defined for float numbers and not for integers too.  
I had been told this, but I had forgotten it.  
Maybe because it didn’t quite convince me why there is no _Inf_ for integers.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [December 27, 2021, 12:48pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/9 "2021-12-27T12:48:59Z")

</div>

a small adaptation

```julia
[foo[k] for k in bar if k in keys(foo)]

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 27, 2021, 4:18pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/10 "2021-12-27T16:18:03Z")

</div>

@rocco_sprmnt21, silent failures may not be a good idea. It might be better something like (_improved with feedback from_ @gustaphe):

```julia
[haskey(foo, k) ? foo[k] : missing for k in bar] 

```

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [December 27, 2021, 4:21pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/11 "2021-12-27T16:21:09Z")

</div>

Then `get.(Ref(foo), bar, missing)` is nicer to me.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 27, 2021, 4:22pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/12 "2021-12-27T16:22:46Z")

</div>

Or `get.((foo,), bar, missing)`  
They are nicer but benchmark here twice as slow as the comprehension.  
What about on your end?

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [December 27, 2021, 4:26pm UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/13 "2021-12-27T16:26:00Z")

</div>

Also `haskey(y, x)` is better than `x in keys(y)`.

---

<div class="post-metadata">

**Author:** ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)\
**Post date:** [December 30, 2021, 2:34am UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/14 "2021-12-30T02:34:03Z")

</div>

> [@gustaphe](#):
>
> `get.(Ref(foo), bar, missing)` is nicer to me.

That’s nice! 😀 The list comprehension is very natural in Python though, which can bias one’s appreciation.

Of dubious interest, but possibly worthy of note:

```julia
using BenchmarkTools
const dict = Dict(i => j for (j,i) in enumerate('A':'Z'))
const keys = collect('B':'Y')

@benchmark get.(Ref(dict), keys, missing)
BenchmarkTools.Trial: 10000 samples with 590 evaluations.
 Range (min … max): 200.120 ns … 1.306 μs ┊ GC (min … max): 0.00% … 82.69%
 Time (median): 210.534 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 219.662 ns ± 55.169 ns ┊ GC (mean ± σ): 1.39% ± 4.74%

   ▃▇▇█▇▆▆▆▅▄▃▃▃▂▂▂▃▂▁ ▂
  ▇█████████████████████████▇█▇▇▇▇▅▇▇▇▇▆▇▆▅▇▅▅▅▆▅▅▄▅▅▅▇▆▆▆▅▄▅▄ █
  200 ns Histogram: log(frequency) by time 313 ns <

 Memory estimate: 280 bytes, allocs estimate: 3.

@benchmark [haskey(dict, k) ? dict[k] : missing for k in keys] 
BenchmarkTools.Trial: 10000 samples with 257 evaluations.
 Range (min … max): 299.370 ns … 3.284 μs ┊ GC (min … max): 0.00% … 89.86%
 Time (median): 307.296 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 323.600 ns ± 101.617 ns ┊ GC (mean ± σ): 1.00% ± 3.26%

  █▅▆▄▄▃▁ ▁▄▂▁▁ ▁
  ███████▇███████▇▇▇▆▆▇▆▇█▇▆▅▅▆▅▆▆▆▆▆▆▅▅▃▆▆▅▅▅▅▅▄▃▃▂▄▄▄▂▄▄▄▄▃▄▄ █
  299 ns Histogram: log(frequency) by time 555 ns <

 Memory estimate: 256 bytes, allocs estimate: 1.

```

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [December 30, 2021, 7:30am UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/15 "2021-12-30T07:30:28Z")

</div>

But broadcasting is very natural in Julia, and faster in this case (indeed probably in most cases where it applies) 😃

---

<div class="post-metadata">

**Author:** ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)\
**Post date:** [December 30, 2021, 7:44am UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/16 "2021-12-30T07:44:59Z")

</div>

Indeed, broadcasting is great. You’re right the median time is smaller, but there are 3 allocations vs 1 allocation with comprehension. Is that not a tie of sorts?

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [December 30, 2021, 10:42am UTC](https://discourse.julialang.org/t/how-to-get-values-of-dictionary-by-using-array-of-keys/73650/17 "2021-12-30T10:42:22Z")

</div>

We should really be trying with a key vector containing some non-existing keys.

```julia
julia> using BenchmarkTools
julia> const dict = Dict(i => j for (j, i) in enumerate('A':'N'));
julia> const keys = 'H':'Z';
julia> @benchmark [haskey(dict, k) ? dict[k] : missing for k in keys]
BenchmarkTools.Trial: 10000 samples with 671 evaluations.
 Range (min … max): 185.680 ns … 890.450 ns ┊ GC (min … max): 0.00% … 74.12%
 Time (median): 188.527 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 195.079 ns ± 38.636 ns ┊ GC (mean ± σ): 1.28% ± 5.32%

  ██▄▂▁ ▂
  █████▇█▆▅▄▆▄▇▇▆▄▁▄▁▄▅▃▄▇▆▄▅▅▆▄▅▁▄▄▃▃▄▃▄▄▄▄▆▃▄▅▆▁▅▅▄▅▄▅▄▅▅▇█▆▇ █
  186 ns Histogram: log(frequency) by time 346 ns <

 Memory estimate: 448 bytes, allocs estimate: 2.

julia> @benchmark get.(Ref(dict), keys, missing)
BenchmarkTools.Trial: 10000 samples with 651 evaluations.
 Range (min … max): 188.880 ns … 1.158 μs ┊ GC (min … max): 0.00% … 82.22%
 Time (median): 192.018 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 198.881 ns ± 57.219 ns ┊ GC (mean ± σ): 2.24% ± 6.31%

  ▇█▅▁ ▂
  ████▇▃▄▃▁▅▅▄▅▄▁▃▃▁▁▁▁▃▁▃▁▁▁▁▄▁▁▁▁▁▁▁▁▁▁▁▃▁▃▄▅▄▄▅▄▄▄▅▄▅▅▄▆▇▇▇ █
  189 ns Histogram: log(frequency) by time 350 ns <

 Memory estimate: 472 bytes, allocs estimate: 4.

julia> @benchmark [get(dict, k, missing) for k in keys]
BenchmarkTools.Trial: 10000 samples with 788 evaluations.
 Range (min … max): 160.060 ns … 811.277 ns ┊ GC (min … max): 0.00% … 69.18%
 Time (median): 161.849 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 166.790 ns ± 35.890 ns ┊ GC (mean ± σ): 1.66% ± 5.97%

  █▅▃ ▁
  ███▇▅▆▇▅▃▃▃▃▃▁▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▁▁▁▁▁▁▃▁▁▁▁▁▃▃▁▁▄▅▄▄▄▄▃▅▄▅▆▇▅▇ █
  160 ns Histogram: log(frequency) by time 316 ns <

 Memory estimate: 448 bytes, allocs estimate: 2.

julia> @benchmark Union{Int64, Missing}[get(dict, k, missing) for k in keys]
BenchmarkTools.Trial: 10000 samples with 903 evaluations.
 Range (min … max): 123.165 ns … 622.011 ns ┊ GC (min … max): 0.00% … 77.72%
 Time (median): 124.857 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 128.293 ns ± 26.097 ns ┊ GC (mean ± σ): 1.25% ± 4.98%

  ▇█▄▃ ▁
  ████▇▆▅▃▄▁▃▃▁▁▄▄▁▁▃▁▁▁▁▃▃▁▁▁▁▃▁▃▁▁▃▁▁▄▅▅▅▆▄▁▅▆▄▄▆▅▄▄▅▄▃▅▆▅▅▇█ █
  123 ns Histogram: log(frequency) by time 210 ns <

 Memory estimate: 240 bytes, allocs estimate: 1.

```

The compromise method is actually the fastest one here. I’m a bit miffed that the more elegant call is worse from that perspective.
