我想在Julia中找到一种简洁的语法,以向量化方式索引字典。在R中,我将执行以下操作:
dict <- c("a" = 1, "b" = 2)
keys <- c("a", "a", "b", "b", "a")
dict[keys]
在朱莉娅中,如果我有一个dict
和keys
这样的人,
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语法?
答案 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