字典的向量化索引

时间:2019-03-07 01:38:22

标签: julia

我想在Julia中找到一种简洁的语法,以向量化方式索引字典。在R中,我将执行以下操作:

dict <- c("a" = 1, "b" = 2)
keys <- c("a", "a", "b", "b", "a")
dict[keys]

在朱莉娅中,如果我有一个dictkeys这样的人,

dict = Dict(:a => 1, :b => 2)
keys = [:a, :a, :b, :b, :a]

然后我可以使用列表理解来达到预期的结果:

julia> [dict[key] for key in keys]
5-element Array{Int64,1}:
 1
 1
 2
 2
 1

是否有更简洁的矢量化语法,类似于R语法?

4 个答案:

答案 0 :(得分:4)

getindex.(Ref(dict), keys)

您可以将其包装在Ref中,因此无需[]

答案 1 :(得分:3)

这是一个小宏(使用出色的MacroTools包):

using MacroTools
macro vget(ex)
    @capture(ex, dict_.[idxvec_])
    :(map(i->$dict[i], $idxvec)) |> esc
end

然后您可以:

d = Dict(:a => 1, :b => 2)
ks = [:a, :a, :b, :b, :a]

@vget d.[ks]

我可能不想在生产代码中使用它,例如您的列表理解或简单的地图:map(i->d[i], ks),更具可读性/明确性/标准性,但它好玩:D

答案 2 :(得分:3)

如果您将经常使用字典作为查找表,那么可能值得创建一个闭包以用作查找功能:

make_lookup(dict) = key -> dict[key]    

dict = Dict(:a => 1, :b => 2)

lookup = make_lookup(dict)

然后,您可以矢量化方式使用lookup

julia> keys = [:a, :a, :b, :b, :a];

julia> lookup.(keys)
5-element Array{Int64,1}:
 1
 1
 2
 2
 1

答案 3 :(得分:2)

您可以使用getindex的矢量化版本:

julia> getindex.([dict], keys)
5-element Array{Int64,1}:
 1
 1
 2
 2
 1

请注意,dict被包装在一个数组中,因此getindex不会尝试通过字典的元素进行广播:

julia> getindex.(dict, keys)
ERROR: ArgumentError: broadcasting over dictionaries and `NamedTuple`s is reserved
Stacktrace:
 [1] broadcastable(::Dict{Symbol,Int64}) at ./broadcast.jl:615
 [2] broadcasted(::Function, ::Dict{Symbol,Int64}, ::Array{Symbol,1}) at ./broadcast.jl:1164
 [3] top-level scope at none:0