Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Julia map on a Dict of Dicts?

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...)

like image 722
Florian Oswald Avatar asked Jun 02 '14 15:06

Florian Oswald


People also ask

How do you use Dict in Julia?

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.

How do you check if a key is in a dictionary Julia?

To test for the presence of a key in a dictionary, use haskey or k in keys(dict) . Base. eltype — Function.

Are Dictionaries slow in Julia?

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).

Are Dictionaries mutable in Julia?

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.


2 Answers

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]
like image 181
DSM Avatar answered Sep 28 '22 05:09

DSM


got an answer on the mailing list:

map(dfun,values(d))
like image 44
Florian Oswald Avatar answered Sep 28 '22 04:09

Florian Oswald