我想要一个接受 aDict或 aNamedTuple作为输入的接口,但总是将输入转换为 a NamedTuple。
给定一个 Dict
julia> dd = Dict(:a => 1, :b => 2)
Dict{Symbol,Int64} with 2 entries:
:a => 1
:b => 2
Run Code Online (Sandbox Code Playgroud)
我可以将其转换为NamedTuplewith
julia> (; dd...)
(a = 1, b = 2)
Run Code Online (Sandbox Code Playgroud)
但是,这两者都分配了令人惊讶的(对我而言)数量
julia> using BenchmarkTools
julia> @btime (; $dd...);
1.033 ?s (12 allocations: 896 bytes)
Run Code Online (Sandbox Code Playgroud)
它不适用于嵌套Dicts,我想将其转换为嵌套NamedTuples
julia> dd_nested = Dict(:a => 1, :b => Dict(:x => 3, :y => 4))
Dict{Symbol,Any} with 2 entries:
:a => 1
:b => Dict(:y=>4,:x=>3)
julia> (; dd_nested...)
(a = 1, b = Dict(:y => 4,:x => 3))
Run Code Online (Sandbox Code Playgroud)
其中所需的输出等于
julia> (a = 1, b = (x = 3, y = 4))
(a = 1, b = (x = 3, y = 4))
Run Code Online (Sandbox Code Playgroud)
关于什么:
unzip(d::Dict) = (;(p.first => unzip(p.second) for p in d)...)
unzip(d) = d
Run Code Online (Sandbox Code Playgroud)
样品测试:
julia> unzip(dd)
(a = 1, b = (y = 4, x = 3))
Run Code Online (Sandbox Code Playgroud)
关于内存分配NamedTupleTools.jl,内存占用似乎略小。但是在任何一种情况下,您都在这里创建了相当多的数据结构,因此很可能您无法以更便宜的方式完成它。