如何打乱一系列数字,然后将其拆分为一定长度的子数组?

Mas*_*son 5 julia

假设我有一个 range 1:N,我想将范围打乱为随机顺序,然后将生成的打乱数组拆分为最多128元素长的子数组。我怎样才能做到这一点?

这个问题是基于 JuliaLang Slack 频道上出现的一个问题。

Mas*_*son 4

shuffle标准库中的函数Random可用于将容器打乱为随机顺序:

\n\n
julia> using Random: shuffle\n\njulia> shuffle(1:10)\n10-element Array{Int64,1}:\n  6\n  9\n  3\n  2\n 10\n  1\n  8\n  7\n  5\n  4\n
Run Code Online (Sandbox Code Playgroud)\n\n

Iterators.partitionJulia 的函数Base可用于以固定长度的块形式迭代可迭代对象:

\n\n
julia> using Base.Iterators: partition\n\njulia> partition(1:20, 7)\nBase.Iterators.PartitionIterator{UnitRange{Int64}}(1:20, 7)\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,partition默认情况下返回一个惰性迭代器,因此如果我们想要实现实际结果,我们需要collect它:

\n\n
julia> collect(partition(1:20, 7))\n3-element Array{UnitRange{Int64},1}:\n 1:7\n 8:14\n 15:20\n
Run Code Online (Sandbox Code Playgroud)\n\n

把这一切放在一起,我们有

\n\n
julia> using Random: shuffle\n\njulia> using Base.Iterators: partition\n\njulia> shuffle_partition(N; chunk_size=128) = (collect \xe2\x88\x98 partition)(shuffle(1:N), chunk_size)\nshuffle_partition (generic function with 1 method)\n\njulia> shuffle_partition(503)\n4-element Array{SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true},1}:\n [313, 51, 117, 373, 381, 340, 342, 415, 423, 453  \xe2\x80\xa6  201, 178, 167, 242, 2, 76, 146, 439, 363, 448]\n [115, 121, 306, 440, 295, 181, 30, 280, 388, 227  \xe2\x80\xa6  362, 39, 317, 171, 55, 214, 261, 251, 96, 9]\n [486, 248, 161, 319, 325, 176, 80, 369, 434, 209  \xe2\x80\xa6  442, 350, 273, 419, 130, 305, 192, 482, 265, 234]\n [460, 31, 400, 466, 220, 447, 119, 446, 198, 141  \xe2\x80\xa6  226, 438, 74, 152, 203, 303, 378, 231, 458, 194]\n\njulia> length.(ans)\n4-element Array{Int64,1}:\n 128\n 128\n 128\n 119\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

这个答案是基于 Slack 上找到的答案。

\n

  • 有一个特定的函数只是用来创建排列,“randperm(n)” (2认同)