Avoiding zeros in ArrayReshape
list = {1, 2, 3, 4, 5, 6, 7, 8};
Partition[list, UpTo[3]]
{{1, 2, 3}, {4, 5, 6}, {7, 8}}
It seems that using ArrayReshape
and modifying, if needed, the last entry to remove trailing zeros is faster than using Partition
or using Inactive @ Nothing
padding:
ClearAll[f1, f2, f3, f4]
f1 = Partition[#, UpTo[#2]] &; (* from Okkes's answer *)
f2 = Partition[#, #2, #2, 1, {}] &;
f3 = Activate @ ArrayReshape[#,
{Ceiling[Length[#]/#2], #2}, Inactive @ Nothing] &; (* from MarcoB's answer *)
f4 = Module[{p = ArrayReshape[#, {Floor[Length[#]/#2], #2}], m = Mod[Length@#, #2]},
If[m == 0, p, Join @@ {p, {#[[-m ;;]]}}]] &;
Timings:
n = 999999;
k = 199;
list = Range[n];
First[RepeatedTiming[r1 = f1[list, k]]]
0.078
First[RepeatedTiming[r2 = f2[list, k]]]
0.075
First[RepeatedTiming[r3 = f3[list, k]]]
0.094
First[RepeatedTiming[r4 = f4[list, k]]]
0.012
r1 == r2 == r3 == r4
True
When n
is divisible by k
(so that ArrayReshape
produces a rectangular array with no paddings):
k = 99;
First[RepeatedTiming[r1 = f1[list, k]]]
0.083
First[RepeatedTiming[r2 = f2[list, k]]]
0.075
First[RepeatedTiming[r3 = f3[list, k]]]
0.0072
First[RepeatedTiming[r4 = f4[list, k]]]
0.0071
r1 == r2 == r3 == r4
True
Using Partition
with UpTo
is clearly the most expedient answer here, as shown above. However, this got me wondering how one could force ArrayReshape
into service anyway, just for fun. For instance, we could twist the use of the padding parameter in ArrayReshape
to force it to pad with Nothing
(or the vanishing function ##&[]
), as in either of the following, which is then removed when evaluated:
ArrayReshape[Range[8], {3, 3}, Hold@Nothing] // ReleaseHold
ArrayReshape[Range[8], {3, 3}, Inactive@Nothing] // Activate
{{1, 2, 3}, {4, 5, 6}, {7, 8}}
After posting the answer, I refreshed the page to see that this was brought up in comments as well.