Named tuple, numbers as keys

So it looks as though you can’t use numbers as keys for a named tuple? I do

    a = (; zip(collect(1:2), wt_pyramid))

and get

    ERROR: syntax: invalid named tuple element "zip(collect(1:2), wt_pyramid)" around REPL[84]:1

I’m trying to put the named tuple in a StructArray, for what it’s worth.

Also, I’m new to Julia. What’s the semicolon doing before the zip in the call?
Thanks,
– Markos

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.

3 Likes

Understood on using a regular array.

I forgot to type the splat but it works fine with it for string names. (wrapping them in Symbol first)

I’m just trying to keep my data organized. Trying to do two things:

  1. generate a wavelet transform at n levels, which as I have coded it, gives me back a StructArray of the four wavelet bands at each level. I.E. Image goes to (level 1, (“LL”, “LH”, “HL”, “HH”); level 2 (“LL”, “LH”, “HL”, “HH”)
  2. Then, for each of these new images, I’d like to do statistical processing of the images, which returns a StructArray of a number of features. (“energy”, “entropy”, “neighborhood mean” etc…)

I’d like to keep the labels of each image with it, so as to keep track, and also potentially run PCA on the resulting chain of operations.

That is probably a more abstract answer than you wanted, but I’d be glad to hear of how people approach similar problems of pyramided data here.

Thanks,
– Markos.

Not that I would necessarily advise it, but symbols can be arbitrary data, but the syntax becomes cumbersome if they’re not literals:

julia> a = (; (zip(map(Symbol, collect(1:2)), ("a", "b")))...)
(var"1" = "a", var"2" = "b")

julia> a[:var"1"]
"a"