[ i for i in 1:10]
What is this called and how exactly does it work? I get how it’s used (wonderfully convenient), but what is this exactly equivalent to? What and how does it allocate? When should and shouldn’t I use it?
[ i for i in 1:10]
What is this called and how exactly does it work? I get how it’s used (wonderfully convenient), but what is this exactly equivalent to? What and how does it allocate? When should and shouldn’t I use it?
It’s called a list comprehension Single- and multi-dimensional Arrays · The Julia Language
but what is this exactly equivalent to?
It is a syntax for lazy map, filter, and a products over iterators. That is,
If you write
[f(x, y) for x in xs, y in ys if g(x, y)]
then that is equivalent to
itr1 = Iterators.product(xs, ys)
itr2 = Iterators.filter(((x, y),) -> g(x, y), itr1)
itr3 = Iterators.map(((x, y),) -> f(x, y), itr2)
collect(itr3)
allocating an array, usually without any intermediates.
If you instead wrote
(f(x, y) for x in xs, y in ys if g(x, y))
then that would be called a “generator comprehension” and this would not do the final collect
stage, just returning an unmaterialized iterator.
The name i normally hear is ‘array comprehension’, since, unlike python’s lists, Julia comprehensions produce arrays.
I just call them list comprehensions (or just ‘comprehensions’), and I think a lot of the community does too, but sure, if you want to be as precise about it as possible, one can call it an array comprehension.
I guess you feel that the word ‘list’ here should always refer to a ‘linked list’, but to be honest I think linked lists are so irrelevant in julia-land that they don’t really deserve to reserve the name ‘list’. As far as I’m concerned, our arrays are lists of items. They’re just not implemented as linked list structures.
I mainly meant that I’ve almost only ever heard ‘array comprehension’ on this forum, and whenever someone says ‘list comprehension’ they were corrected. So I assumed the former was the official name.
Huh. If that’s the case I never noticed. Either way, ‘array’ would be a more accurate name so good to point out.
Out of curiosity, I searched for the usage of either of those phrases over the last year on this forum… and it turns out they were used the exact same number of times:
28 uses of “array comprehension” vs 28 uses of “list comprehension”
I believe ‘array comprehension’ is up by one, actually😉
There are other distinctions between “list” and “array” that are probably more relevant: Julia array comprehensions can produce arrays of any dimensionality, and generally try to mimic the axes
of the things you iterate over (e.g. offset axes, named axes, block arrays):
julia> using OffsetArrays
julia> X = -1:1;
julia> Y = OffsetArray(reshape(1:6,3,:), 2, -3);
julia> [(x,y) for x in X, y in Y]
3×3×2 OffsetArray(::Array{Tuple{Int64, Int64}, 3}, 1:3, 3:5, -2:-1) with eltype Tuple{Int64, Int64} with indices 1:3×3:5×-2:-1:
[:, :, -2] =
(-1, 1) (-1, 2) (-1, 3)
(0, 1) (0, 2) (0, 3)
(1, 1) (1, 2) (1, 3)
[:, :, -1] =
(-1, 4) (-1, 5) (-1, 6)
(0, 4) (0, 5) (0, 6)
(1, 4) (1, 5) (1, 6)
(Neither are Python lists, which are simply arrays of object pointers internally, exactly like Vector{Any}
in Julia.)