# Iterator over variable number of arguments

Suppose you want to define an iterator over the vertices of the n-dimensional unit hypercube.

In two dimensions, this is:

``````julia> using Iterators
julia> collect(Iterators.product([-1, 1], [-1, 1]))
4-element Array{Tuple{Int64,Int64},1}:
(-1,-1)
(1,-1)
(-1,1)
(1,1)
``````

and similarly for 3d:

``````julia> collect(Iterators.product([-1, 1], [-1, 1], [-1, 1]))
8-element Array{Tuple{Int64,Int64,Int64},1}:
(-1,-1,-1)
(1,-1,-1)
(-1,1,-1)
(1,1,-1)
(-1,-1,1)
(1,-1,1)
(-1,1,1)
(1,1,1)
``````

How to do when the dimension is not known a priori?

background: in Python this is achieved with `list(itertools.product([-1, 1], repeat=n))`, or even using tuple unpacking into arguments list as in `list(itertools.product(*([-1, 1] for i in range(n))))`.

I think Base.Cartesian might have an answer?

https://docs.julialang.org/en/stable/devdocs/cartesian/

All of the example show loops but you can use it to make a generator.

Does this do what you want?

``````julia> n=3
3

julia> collect(Iterators.product([[1,-1] for i=1:n]...))
8-element Array{Tuple{Int64,Int64,Int64},1}:
(1,1,1)
(-1,1,1)
(1,-1,1)
(-1,-1,1)
(1,1,-1)
(-1,1,-1)
(1,-1,-1)
(-1,-1,-1)
``````
1 Like

yes ! this `...` or splat operator does the job.

thanks you both.

Just for the sake of mentioning it. There is a `CornerIterator` in `ImageTransformations` that is used internally for the use-case of iterating over the corners of a n-dim hyper-cube (or hyper-rectangle I guess).

``````julia> using ImageTransformations

julia> collect(ImageTransformations.CornerIterator(CartesianIndex(-1,-1), CartesianIndex(1,1)))
2Ă—2 Array{CartesianIndex{2},2}:
CartesianIndex{2}((-1,-1))  CartesianIndex{2}((-1,1))
CartesianIndex{2}((1,-1))   CartesianIndex{2}((1,1))

julia> collect(ImageTransformations.CornerIterator(CartesianIndex(-1,-1,-1), CartesianIndex(1,1,1)))
2Ă—2Ă—2 Array{CartesianIndex{3},3}:
[:, :, 1] =
CartesianIndex{3}((-1,-1,-1))  CartesianIndex{3}((-1,1,-1))
CartesianIndex{3}((1,-1,-1))   CartesianIndex{3}((1,1,-1))

[:, :, 2] =
CartesianIndex{3}((-1,-1,1))  CartesianIndex{3}((-1,1,1))
CartesianIndex{3}((1,-1,1))   CartesianIndex{3}((1,1,1))
``````
1 Like

Can it also iterate over â€śedgesâ€ť in a hyper cube?

If you are asking me if I know of a similar iterator somewhere that goes along each edge, then I am afraid I donâ€™t.