如何创建任意层嵌套的for循环

6
我可以像这样完成一个两级嵌套循环
for i1 in 1:n
  for i2 in 1:n
    do something with (i1,i2)      

我要如何将这个扩展到任意嵌套层数的循环中呢?

举例来说,在Python中,我可以使用以下代码循环n^m的笛卡尔积:

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

喜欢

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)

感谢@tholy的评论。我已成功应用Iterators.jl。由于我是Julia的新手,所以我的代码可能有些拙劣。

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)
3个回答

6
在v0.5版本中,Base中有一个产品迭代器,因此您现在可以将其编写为Base.product(fill(1:2,3)…)fill会生成一个带有某个值重复多次的数组;我认为这比创建一个1元素数组并调用repmat更加优雅。

1

Cartesian.jl可能会在一定程度上提供您所需的功能。

我对如何使用它知之甚少,但我至少能够复制您Python代码的相同结果,不过这可能不足够“任意”,因为我无法将循环体中的3替换为变量。

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)

希望了解这个包的人可以给出更好的答案。
额外补充:Julia接受这种简洁的循环语法:
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)

尽管如此,我想可能存在一种更简单的方法来做到这一点,或者至少在Julia中编写一个itertools.product函数应该不难。 - Cristóvão D. Sousa
4
Cartesian 旨在编写高性能代码。如果这是你想要的,那么它可能适合你——在性能方面,没有其他东西可以与之媲美。然而,如果你想要更易于使用的东西,可以尝试 Iterators.jl 包。该包目前没有文档,但 test.jl 脚本应该能帮助你入门。 - tholy
1
谢谢,我已经成功地应用了Iterators.jl。如果您能单独发布一篇条目,我可以将其标记为被接受的答案(也许将我的示例移动到被接受的答案中)。 - Wai Yip Tung

0
通常来说,递归是指一个函数调用自身的情况。如果您能提供更详细的问题,我可以给您更详细的回答。

1
谢谢。我已经添加了一个Python示例,希望能使它更清晰明了。 - Wai Yip Tung

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接