As @yuyichao alluded to, there is a difference between the fill and comprehension techniques: do you want an array of the same empty array, or an array of different empty arrays? This will affect what happens if you modify one of the arrays:
julia> a = fill([], 5)
5-element Array{Array{Any,1},1}:
Any[]
Any[]
Any[]
Any[]
Any[]
julia> push!(a[1], "hello"); a
5-element Array{Array{Any,1},1}:
Any["hello"]
Any["hello"]
Any["hello"]
Any["hello"]
Any["hello"]
julia> b = [[] for i=1:5]
5-element Array{Array{Any,1},1}:
Any[]
Any[]
Any[]
Any[]
Any[]
julia> push!(b[1], "hello"); b
5-element Array{Array{Any,1},1}:
Any["hello"]
Any[]
Any[]
Any[]
Any[]
Note that the [[]]*5 construct in Python is similar to fill here, in that it makes a list of 5 references to the same empty list:
In [1]: a = [[]]*5; a
Out[1]: [[], [], [], [], []]
In [2]: a[0].append('hello'); a
Out[2]: [['hello'], ['hello'], ['hello'], ['hello'], ['hello']]
The use case is to construct array of multi-indices. Starting from an empty array I gradually want to build up a matrix in which every row represents a multi-index. So, the output of the algorithm is something like this:
Or a Vector of SVector (from StaticArrays.jl), if you want to take advantage of compile-time optimizations for the length of your multi-index, not to mention more efficient inline storage in the array. A Vector of SVector can also be converted to a Matrix at the end with a simple reinterpret (no copies) if needed.
An array of an immutable container with a fixed number of entries (like a CartesianIndex or a StaticArray) is typically vastly more efficient than a generic array of arrays. An array of arrays is essentially like an array of pointers, or a sometype** in C/C++, whereas an array of immutables is like an array of structs that are stored inline. (And the fact that the length of these immutable containers is known to the compiler enables an array of optimization possibilities that can make a big difference for small containers).