What am I doing wrong in this array comprehension?

In the midst of writing some ring arithmetic code, I found my Julia session producing very strange results for an element-wise modulo operation.

v = collect(1:20)
[(i, n) for i=1:20, n=(v .^2 .% 17) if i == n] # produces 19 tuples of (n, n)


Show that the tuple isn't incrementing the index, or is throwing out the
value assigned to `i`. Whatever it is doing, applying the same logic in
a loop shows the only found element is unity.
function test_that_above_is_incorrect()
    out = []
    for (counter, n) in enumerate(1:20)
        if (n ^2) % 17 == counter
            push!(out, n)
    out # outputs a vector of a single element

I know the logical equivalent with enumerate work correctly i.e.

[(i,n) for (i,n) in enumerate(v) if i == ((n ^ 2) % 17)]

is just fine.

So where did I go astray in the initial comprehension?

Thanks in advance

The comprehension generates the outer product of the two iterators.

julia> [(i,j) for i=1:3, j=1:3]
3×3 Matrix{Tuple{Int64, Int64}}:
 (1, 1)  (1, 2)  (1, 3)
 (2, 1)  (2, 2)  (2, 3)
 (3, 1)  (3, 2)  (3, 3)

For equivalence with enumerate you should zip (or use pairs):
[(i, n) for (i,n) in zip(1:20,v) if i==(n^2)%17]
what you have is a double loop instead.

That’s interesting. In additional testing, it seems the if just selects a column of that outer product. Thanks for clarifying

I was under the impression the double loop was a bit more explicit, a la

[(i, n) for i in 1:20 for n in (v .^ 2 % 17) if i==n]

You get a product iterator either way, but using commas will get you a matrix (or higher dim tensor with more components).