Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make arbitrary level of nested for-loop

Tags:

julia

I can do a two level nested loop like this

for i1 in 1:n
  for i2 in 1:n
    do something with (i1,i2)      

How do I extend this into arbitrary level of nested loop?

For example, I can do this in Python to loop the cartesian product of n^m

for i in (itertools.product(xrange(n),repeat=m)):

Like

for i in (itertools.product(xrange(2),repeat=3)):
    print i

(0, 0, 0)
(0, 0, 1)
(0, 1, 0)
(0, 1, 1)
(1, 0, 0)
(1, 0, 1)
(1, 1, 0)
(1, 1, 1)

Thank you for @tholy's comment. I have successfully applied Iterators.jl. I'm a Julia newbie so my code maybe clumsy.

for i in product(repmat(Any[1:2],3)...)
    println(i)
end

(1,1,1)
(2,1,1)
(1,2,1)
(2,2,1)
(1,1,2)
(2,1,2)
(1,2,2)
(2,2,2)
like image 471
Wai Yip Tung Avatar asked Feb 22 '14 05:02

Wai Yip Tung


2 Answers

In v0.5 there is a product iterator in Base, so you can now write this as Base.product(fill(1:2,3)...). fill produces an array with a value repeated some number of times; I find this a bit more elegant than creating a 1-element array and calling repmat.

like image 74
Jeff Bezanson Avatar answered Nov 15 '22 15:11

Jeff Bezanson


The Cartesian.jl package may provide the functionality you want to some extent.

I know very little about how to use it, but I was able to at least reproduce the same result of your Python code, however it may be not enough "arbitrary" as I was not able to replace the 3 in the loop body by a variable.

julia> using Cartesian
julia> @nloops 3 i d->0:1 begin
          println(@ntuple 3 i)
       end
(0,0,0)
(1,0,0)
(0,1,0)
(1,1,0)
(0,0,1)
(1,0,1)
(0,1,1)
(1,1,1)

Hopefully someone knowing well this package can give a better answer.

Just an extra: Julia accepts this nice loop syntax:

julia> for i in 1:2, j in 1:3
           println((i, j))
       end
(1,1)
(1,2)
(1,3)
(2,1)
(2,2)
(2,3)
like image 29
Cristóvão D. Sousa Avatar answered Nov 15 '22 15:11

Cristóvão D. Sousa