2016-11-19 60 views
7

如果我有这样一个字典作为如何在Julia中翻译字典?

my_dict = Dict(
    "A" => "one", 
    "B" => "two", 
    "C" => "three" 
) 

什么是扭转键/值映射关系的最佳方式?

+0

您是否必须担心映射到相同值的两个不同键,或者不是? – DSM

回答

11

的一种方法是通过遍历键/值对,沿途交换他们使用的理解来构建新字典:

julia> Dict(value => key for (key, value) in my_dict) 
Dict{String,String} with 3 entries: 
    "two" => "B" 
    "one" => "A" 
    "three" => "C" 

当交换键和值,您可能希望保留请记住,如果my_dict具有重复值(例如"A"),则新字典可能包含的键较少。另外,新字典中按键"A"定位的值可能不是您期望的值(Julia的字典不以任何容易确定的顺序存储其内容)。

14

假设你不必担心重复值碰撞钥匙,mapreverse你可以使用:

julia> my_dict = Dict("A" => "one", "B" => "two", "C" => "three") 
Dict{String,String} with 3 entries: 
    "B" => "two" 
    "A" => "one" 
    "C" => "three" 

julia> map(reverse, my_dict) 
Dict{String,String} with 3 entries: 
    "two" => "B" 
    "one" => "A" 
    "three" => "C" 
+0

这是最好的答案! –

4

使这个一会儿回来,可能有冲突值

function invert_dict(dict, warning::Bool = false) 
    vals = collect(values(dict)) 
    dict_length = length(unique(vals)) 

    if dict_length < length(dict) 
     if warning 
      warn("Keys/Vals are not one-to-one") 
     end 

     linked_list = Array[] 

     for i in vals 
      push!(linked_list,[]) 
     end 

     new_dict = Dict(zip(vals, linked_list)) 

     for (key,val) in dict 
      push!(new_dict[val],key) 
     end 
    else 
     key = collect(keys(dict)) 

     counter = 0 
     for (k,v) in dict 
      counter += 1 
      vals[counter] = v 
      key[counter] = k 
     end 
     new_dict = Dict(zip(vals, key)) 
    end 

    return new_dict 
end 
词典

使用此如果如果一个关键成为重复,你将有一个列表与所有值,所以没有数据将会丢失,即

julia> a = [1,2,3] 
julia> b = ["a", "b", "b"] 

julia> Dict(zip(a,b)) 
Dict{Int64,String} with 3 entries: 
    2 => "b" 
    3 => "b" 
    1 => "a" 

julia> invert_dict(ans) 
Dict{String,Array} with 2 entries: 
    "b" => Any[2,3] 
    "a" => Any[1]