The keys are symbols, like Julia identifiers. So you can’t use a number in the same way that you can use a number as an identifier, e.g. you can’t have a variable or a struct field named 3. You should think of a named tuple as an anonymous struct, and the keys are the fields.
That said, you can index by numbers if you want:
julia> nt = (; a = 3, b = 4)
(a = 3, b = 4)
julia> nt[1] # index of first field (a)
3
julia> nt.a # access the same field by name
3
However, if you only want to index by numbers, you don’t need a named tuple at all, just an ordinary tuple.
The semicolon distinguishes the named fields of a named tuple from the unnamed fields of an ordinary tuple.
That being said, just putting a semicolon and then zip(...) won’t work. You’ll need to “splat” an iterator (with ...) into a tuple or named tuple if you want to use them as elements, e.g.:
julia> (; ((:a, 3), (:b, 4))...) # keys and values splatted via ...
(a = 3, b = 4)
julia> (; ((:a, 3), (:b, 4))) # not splatted
ERROR: syntax: invalid named tuple element "((:a, 3), (:b, 4))" around REPL[16]:1
because the elements to construct a named tuple are (:key, value) pairs.
You may be confusing it with the usage for arrays, where ; is a concatenation operator:
julia> [1:3; 4:6]
6-element Vector{Int64}:
1
2
3
4
5
6
That being said, you usually want to use tuples and named tuples when the length and keys are known statically (at compile time), so splatting a zip iterator looks suspicious to me.
What kind of data do you have, and what data structure are you trying to get? Probably there is a better way to go about it.