Julia中替代嵌套for循环的方法

3

给定任意整数a和b,我想创建一个Z_a^b \times Z_a^b中所有不同对的列表。例如,当a=3且b=2时,我希望得到以下数组

[[[0,0],[0,0]],[[0,0],[0,1]],[[0,0],[0,2]],...,[[2,2],[2,1]],[[2,2],[2,2]]] 

我希望在Julia中实现这个功能,但是对于任意的b值,我不知道如何轻松地完成它(即使对于固定的b值,我唯一能想到的方法也是嵌套循环)。有没有一种快速实现的方法?


1
你尝试过使用Iterators.product吗? - DNF
1个回答

4

这是您想要的吗?

julia> Z(a, b) = Iterators.product([0:a-1 for _ in 1:b]...)
Z (generic function with 1 method)

julia> collect(Iterators.product(Z(3,2), Z(3,2))) |> vec
81-element Vector{Tuple{Tuple{Int64, Int64}, Tuple{Int64, Int64}}}:
 ((0, 0), (0, 0))
 ((1, 0), (0, 0))
 ((2, 0), (0, 0))
 ((0, 1), (0, 0))
 ((1, 1), (0, 0))
 ((2, 1), (0, 0))
 ((0, 2), (0, 0))
 ((1, 2), (0, 0))
 ((2, 2), (0, 0))
 ((0, 0), (1, 0))
 ⋮
 ((0, 0), (2, 2))
 ((1, 0), (2, 2))
 ((2, 0), (2, 2))
 ((0, 1), (2, 2))
 ((1, 1), (2, 2))
 ((2, 1), (2, 2))
 ((0, 2), (2, 2))
 ((1, 2), (2, 2))
 ((2, 2), (2, 2))

julia> collect(Iterators.product(Z(4,3), Z(4,3))) |> vec
4096-element Vector{Tuple{Tuple{Int64, Int64, Int64}, Tuple{Int64, Int64, Int64}}}:
 ((0, 0, 0), (0, 0, 0))
 ((1, 0, 0), (0, 0, 0))
 ((2, 0, 0), (0, 0, 0))
 ((3, 0, 0), (0, 0, 0))
 ((0, 1, 0), (0, 0, 0))
 ((1, 1, 0), (0, 0, 0))
 ((2, 1, 0), (0, 0, 0))
 ((3, 1, 0), (0, 0, 0))
 ((0, 2, 0), (0, 0, 0))
 ((1, 2, 0), (0, 0, 0))
 ⋮
 ((3, 1, 3), (3, 3, 3))
 ((0, 2, 3), (3, 3, 3))
 ((1, 2, 3), (3, 3, 3))
 ((2, 2, 3), (3, 3, 3))
 ((3, 2, 3), (3, 3, 3))
 ((0, 3, 3), (3, 3, 3))
 ((1, 3, 3), (3, 3, 3))
 ((2, 3, 3), (3, 3, 3))
 ((3, 3, 3), (3, 3, 3))

请注意,我collect它是为了使结果可见。通常情况下,由于结果集可能非常大,最好使用惰性的Iterators.product并对其进行迭代。

谢谢。然而,当a=4且b=3时似乎出现了问题。我错了吗?它应该总是由两个整数元组组成吗?例如,对于a=3和b=3,它应该是((0,0),(0,0),(0,0)) ((0,0),(0,0),(0,1))等等。对于a=4和b=3,我期望有类似的结果,但现在整数的值可以是0、1、2或3。 - Joshuah Heath
1
Z_a^b 的元素是 b 元组,如果你要将两个 b 元组相乘,你会得到一个包含两个 b 元组的 2 元组。如果你想将包含两个 b 元组的 2 元组转换为包含 2 元组的 b 元组,你可以使用 SplitApplyCombine.jl 包中的 invert 函数。 - Bogumił Kamiński

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