Julian way of comparing two dictionaries

question
dictionary
julian-way

#1

How do you compare two dictionaries?

d1 = Dict(1=>2., 3=>4.)
d2 = Dict(3=>4., 1=>2.)
d3 = Dict(1=>0., 3=>4.)

d1 == d2 # true
d1 == d3 # false

#2

I don’t understand the question. If you type @which d1 == d3, it points to the source code that shows how Julia does it. Is that what you want to know?


#3

@cstjean, I just realized that my problem is something else. I have a test that is evaluating as false, but the dictionaries are the same:

Test Failed
  Expression: GeoStats.mapping(mapper1D, :value) == Dict(23 => 0.0347232, 45 => 0.282193, 57 => 0.729891, 68 => 0.341069, 34 => 0.192102, 90 => 0.549381, 79 => 0.577662, 12 => 0.980171, 1 => 0.191499)
   Evaluated: Dict(23=>0.0347232,45=>0.282193,57=>0.729891,68=>0.341069,34=>0.192102,90=>0.549381,79=>0.577662,12=>0.980171,1=>0.191499) == Dict(23=>0.0347232,68=>0.341069,90=>0.549381,12=>0.980171,34=>0.192102,1=>0.191499,79=>0.577662,57=>0.729891,45=>0.282193)

Maybe it is the type of the dictionary entries that is not matching? I will double check it here.


#4

If I copy/paste the evaluation that is failing in the tests in the Julia prompt, it doesn’t fail:

Dict(23=>0.0347232,45=>0.282193,57=>0.729891,68=>0.341069,34=>0.192102,90=>0.549381,79=>0.577662,12=>0.980171,1=>0.191499) == Dict(23=>0.0347232,68=>0.341069,90=>0.549381,12=>0.980171,34=>0.192102,1=>0.191499,79=>0.577662,57=>0.729891,45=>0.282193)

What is the cause of the issue?


#5
julia> d = Dict(23=>0.0347232,45=>0.282193,57=>0.729891,68=>0.341069,34=>0.192102,90=>0.549381,79=>0.577662,12=>0.980171,1=>0.191499);

julia> d == deepcopy(d)
true

works for me


#6

@jw3126, the line I copy/pasted above is working for me as well, do you think it is a rounding issue?


#7

Probably its a rounding issue. Only the first few digits of d are displayed. In your tests you have to dicts whose values are the same only up to the first few digits.

julia> d1 = Dict(1 => 9.87654321)
Dict{Int64,Float64} with 1 entry:
  1 => 9.87654

julia> d2 = Dict(1 => 9.87654322)
Dict{Int64,Float64} with 1 entry:
  1 => 9.87654

julia> using Base.Test

julia> @test d1 == d2
Test Failed
  Expression: d1 == d2
   Evaluated: Dict(1=>9.87654) == Dict(1=>9.87654)

#8

Base does not define isapprox for Dicts. Something like this might be useful.

function Base.isapprox(l::Associative, r::Associative)
    l === r && return true
    if isa(l,ObjectIdDict) != isa(r,ObjectIdDict)
        return false
    end
    if length(l) != length(r) return false end
    for pair in l
        if !in(pair, r, isapprox)
            return false
        end
    end
    true
end

But, allowing tolerances, etc. would be necessary.


#9

And what do you think about function isequal(d1, d2)? Mainly if the Dict contains NaN.