Nat Gillin
Nat Gillin

Reputation: 253

How to access key-value tuples in forward/reverse order for Dict and SortedDict? - Julia

Given a dictionary:

> d = Dict{Int, Int}(1=>123, 2=>51, 4=>23)
Dict{Int64,Int64} with 3 entries:
  4 => 23
  2 => 51
  1 => 123

I could access a dictionary's value by its key, e.g.:

> d[4]
23

Or I could looped through the key-value pairs as such:

> for i in d
         println(i)
       end
4=>23
2=>51
1=>123

I've tried accessing the key as the first element of the list or even i.key, but it doesn't seem to be the right syntax:

julia> for i in d
         println(i.key)
       end
ERROR: type Pair has no field key
 in macro expansion; at ./REPL[22]:2 [inlined]
 in anonymous at ./<missing>:?

julia> for i in d
         println(i[0])
       end
ERROR: BoundsError: attempt to access 4=>23
  at index [0]
 in getindex(::Pair{Int64,Int64}, ::Int64) at ./operators.jl:609
 in macro expansion; at ./REPL[23]:2 [inlined]
 in anonymous at ./<missing>:?

And then I remembered that Julia is not 0th index, so it should be:

> for i in d
         println(i[1], ' ', i[2])
       end
4 23
2 51
1 123

> for i in d
         println(i[1], ' ', i[2])
       end
4 23
2 51
1 123

In this case is the BoundsError somewhat like the Python's IndexError when an index of the list isn't found?

The other part of the question is on SortedDict, how do I access the last Nth element in the SortedDict?

I've tried using the index syntax and I retrieved the value but not the tuple of (key,value).

julia> import DataStructures: SortedDict

julia> sd = SortedDict(d)
DataStructures.SortedDict{Int64,Int64,Base.Order.ForwardOrdering} with 3 entries:
  1 => 123
  2 => 51
  4 => 23

julia> sd[end]
23 

Also, how can I sort the dictionary based on the value?

And, lastly, how to reverse the sorted dict?

I've tried using Base.Order.ReverseOrding but it threw a MethodError:

julia> sd = SortedDict{Base.Order.ReverseOrdering}(d)
ERROR: MethodError: Cannot `convert` an object of type Dict{Int64,Int64} to an object of type DataStructures.SortedDict{Base.Order.ReverseOrdering,D,Ord<:Base.Order.Ordering}
This may have arisen from a call to the constructor DataStructures.SortedDict{Base.Order.ReverseOrdering,D,Ord<:Base.Order.Ordering}(...),
since type constructors fall back to convert methods.
 in DataStructures.SortedDict{Base.Order.ReverseOrdering,D,Ord<:Base.Order.Ordering}(::Dict{Int64,Int64}) at ./sysimg.jl:53

Upvotes: 0

Views: 927

Answers (1)

Kevin L. Keys
Kevin L. Keys

Reputation: 995

I am not a Python user, but the documentation for IndexError looks similar to the documentation for BoundsError. Note that you can always query current Julia documentation with ?, e.g.

?BoundsError

You can sort dictionary keys and values:

d = Dict{Int,Int}(1 => 2, 3 => 4)
k = sort(collect(keys(d)) ### collect() forms an array that you can sort
v = sort(collect(values(d))

but I cannot see why you would want to sort by value. Why not simply use the values as keys?

You can loop through keys or values easily:

for k in keys(d)  ### or "for v in values(d)..."
    println(k)
end

When using SortedDict, make sure that such an ordering makes sense. In this toy example the keys of d are integers, and they have a logical order with isless and isequal; see documentation here.

You can obtain the last entry of a SortedDict with last:

using DataStructures
D = SortedDict(d)
last(D) ### 3=>4

Use the Reverse module to flip the order:

using Reverse
D2 = SortedDict(d, Reverse)

Upvotes: 4

Related Questions