I want to iterate over a collection of dicts and evaluate a function that takes one Dict at a time. In R-speak I have a list of lists and want to lapply my function - which takes a list as input - for each sublist:
function dfun(d::Dict)
println(collect(keys(d)))
println(collect(values(d)))
end
# my dict of dicts
d = [1 => ["a" => 1.1], 2 => ["b" => 3.12]]
[2=>["b"=>3.12],1=>["a"=>1.1]]
# works?
julia> dfun(d[1])
ASCIIString["a"]
[1.1]
# maps?
map(dfun,d)
ERROR: no method dfun((Int64,Dict{ASCIIString,Float64}))
in map at abstractarray.jl:1183
What's the correct way of doing this? I'm surprised it sends (Int64,Dict{ASCIIString,Float64}) to the funciton and not just Dict{ASCIIString,Float64}
(sorry for crossposting - but i think SO is just so much nicer to search...)
A dictionary in Julia can be created with a pre-defined keyword Dict(). This keyword accepts key-value pairs as arguments and generates a dictionary by defining its data type based on the data type of the key-value pairs. One can also pre-define the data type of the dictionary if the data type of the values is known.
To test for the presence of a key in a dictionary, use haskey or k in keys(dict) . Base. eltype — Function.
You could write a caching wrapper. Compared to python, dictionary lookup is very fast. This is ridiculously slow, because it involves a non-inlined runtime call to jl_object_id . At some point in the future it will probably get faster (someone writes an if @generated fallback that treats objects as blobs of memory).
The values of Dictionary are mutable, or "settable", and can be modified via setindex! . However, just like for Array s, new indices (keys) are never created or rearranged this way.
In Julia, iteration over a dictionary is iteration over key/value pairs, not iteration over values (or iteration over keys, as in Python):
julia> for x in d println(x); println(typeof(x)) end
(2,["b"=>3.12])
(Int64,Dict{ASCIIString,Float64})
(1,["a"=>1.1])
(Int64,Dict{ASCIIString,Float64})
so that's why your map is getting (Int64,Dict{ASCIIString,Float64})
-typed args. If you want the values, you could ask for those specifically:
julia> map(dfun, values(d))
ASCIIString["b"]
[3.12]
ASCIIString["a"]
[1.1]
2-element Array{Any,1}:
nothing
nothing
but if you're not returning anything from the function, it feels a little weird to use map
because you're building an unneeded Array of nothing. I'd just do
julia> for v=values(d) dfun(v) end
ASCIIString["b"]
[3.12]
ASCIIString["a"]
[1.1]
got an answer on the mailing list:
map(dfun,values(d))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With