How to make a named tuple from a dictionary?


#1

Is there a simple way to make a named tuple from a Dict{Symbol, T}?


#2

There should be an easier way, but this works:

julia> NamedTuple{tuple(keys(di)...), Tuple{typeof.(collect(values(di)))...,}}((values(di)...,)) 
(a = 1, b = 5.6)```

#3
dictkeys(d::Dict) = (collect(keys(d))...,)
dictvalues(d::Dict) = (collect(values(d))...,)

namedtuple(d::Dict{Symbol,T}) where {T} =
    NamedTuple{dictkeys(d)}(dictvalues(d))

dictionary = Dict(:a => 5, :b => 6, :c => 7)
Dict{Symbol,Int64} with 3 entries:
  :a => 5
  :b => 6
  :c => 7

namedtuple(dictionary)
(a = 5, b = 6, c = 7)

dictionary = Dict(:a => 5, :b => 6.0, :c => "7")
Dict{Symbol,Any} with 3 entries:
  :a => 5
  :b => 6.0
  :c => "7"

namedtuple(dictionary)
(a = 5, b = 6.0, c = "7")

#4

Thanks @mauro3 and @JeffreySarnoff for the replies, it would be nice of you to make a PR!


#5

Is there nowadays a more convenient way to turn a dict into a named tuple?


#6
julia> d = Dict(:a => 1, :b => 2)
Dict{Symbol,Int64} with 2 entries:
  :a => 1                        
  :b => 2

julia> NamedTuple{Tuple(keys(d))}(values(d))
(a = 1, b = 2)

#7

Probably touching internal detail, but…

((; kw...) -> kw.data)(; d...)

also works.


#8

AFAIU values(kw) is the public accessor for kw.data (to turn the keyword iterator into a NamedTuple).


#9

Simply unpack the dict into a tuple.


(a = 1, dict...)



#10

Tada:

julia> (; Dict(:a => 5, :b => 6, :c => 7)...)
(a = 5, b = 6, c = 7)

(Edit: note, that this already worked in Julia 0.7 when NamedTuples first appeared. Sometimes it just takes a bit longer to find the best solution…)