5

I confronted strange behavior in Dictionary collection in Julia. a Dictionary can be defined in Julia like this:

dictionary = Dict(1 => 77, 2 => 66, 3 => 1)

and you can access keys using keys:

> keys(dictionary)

# [output] 
KeySet for a Dict{Int64, Int64} with 3 entries. Keys:
2
3
1

# now i want to make sure Julia consider above order. so i use collect and then i will call first element of it
> collect(keys(dictionary))[1]

# [output] 
2

as you can see the order of keys in keys(dictionary) output is so strange. seems Julia doesn't consider the order of (key=>value) in input! even it doesn't seem to be ordered ascending or descending. How Julia does indexing for keys(dictionary) output?


Expected Output:

> keys(dictionary)

# [output] 
KeySet for a Dict{Int64, Int64} with 3 entries. Keys:
1
2
3

> collect(keys(dictionary))[1]

# [output] 
1

I expect keys(dictionary) give me the keys in the order that I entered them in defining dictionary.

Shayan
  • 5,165
  • 4
  • 16
  • 45

2 Answers2

7

The key order in Dict is currently undefined (this might change in the future).

If you want order to be preserved use OrderedDict from DataStructures.jl:

julia> using DataStructures

julia> dictionary = OrderedDict(1 => 77, 2 => 66, 3 => 1)
OrderedDict{Int64, Int64} with 3 entries:
  1 => 77
  2 => 66
  3 => 1

julia> keys(dictionary)
KeySet for a OrderedDict{Int64, Int64} with 3 entries. Keys:
  1
  2
  3
Bogumił Kamiński
  • 66,844
  • 3
  • 80
  • 107
7

This is nothing specific to Julia but rather a common property of Dictionaries, sometimes even incorporated into the definition thereof

A dictionary is an abstract data type that defines an unordered collection of data as a set of key-value pairs.

One of the most common ways to implement a dictionary is as a hash map / hash table, which is indeed the default implementation of Dictionaries in Julia. Since, in a hash map, objects are stored at a location determined by the hash of the key, the order in which elements are stored is extremely unlikely to match the numeric order of the keys (if, indeed, the keys even are numeric).

If you want a structure similar to a Dictionary but with a stable order, you may consider an OrderedDict from OrderedCollections.jl, or perhaps even just a simple named tuple:

julia> nt = (a = 77, b = 66, c = 1)
(a = 77, b = 66, c = 1)

julia> nt[1]
77

julia> nt[2]
66

julia> nt[3]
1

julia> nt.a
77
cbk
  • 4,225
  • 6
  • 27