Initializing a Dict, is there a more Julia way to do it?

I want to create a dict with as keys Integers in the range 1:lines and as value an empty Vector of Int.
Coming from Python I found this the shortest way to initialize this Dict:

d::Dict{Int, Vector{Int}} = Dict([(k, []) for k in 1:lines])

It works but I was wondering is there a better or more Julia way to do this?

You can use a dict comprehension like (I believe?) in Python:

julia> Dict(k => Int[] for k in 1:5)
Dict{Int64, Vector{Int64}} with 5 entries:
  5 => []
  4 => []
  2 => []
  3 => []
  1 => []
2 Likes

Note, the type annotation seems to be ignored when I run your code. Not sure why that is, but the RHS of your code creates a Dict{Int, Vector{Any}}, and it doesn’t automatically convert when you add that type annotation.

Thanks works very well!

When I run it in my script both nilshg his solution and my code generate the right types!
I’m running with v1.6.2

Weird!

julia> function foo()
       lines = 5
       d::Dict{Int, Vector{Int}} = Dict([(k, []) for k in 1:lines])
       end;


julia> versioninfo()
Julia Version 1.6.1
Commit 6aaedecc44 (2021-04-23 05:59 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, skylake)

julia> foo()
Dict{Int64, Vector{Any}} with 5 entries:
  5 => []
  4 => []
  2 => []
  3 => []
  1 => []

I’ll check the history to see if some change would have affected this.

When I run your code in the REPL I get same result!
but in my script running:

    d::Dict{Int, Vector{Int}} = Dict(k => Int[] for k in 1:lines)
    @show typeof(d)

I get:
typeof(d) = Dict{Int64, Vector{Int64}}

Yes, your code has Int[] and mine does not.

This is expected because assignments in Julia always just return the right-hand side. That means the return value of the expression d::Dict{Int, Vector{Int}} = Dict([(k, []) for k in 1:lines]) is unaffected by the type annotation on the left-hand side.

julia> function foo()
       lines = 5
       d::Dict{Int, Vector{Int}} = Dict([(k, []) for k in 1:lines])
       d
       end;

should do what you want.

2 Likes

Yes that makes it very clear, thanks very much to all!

Interesting!

The Dict{Int, Vector{Any}} is still materialized at some point before the conversion, right? So this code is still inefficient, right?

Yes

3 Likes