Here are two ideas of my own, using a recursive approach:
f1[list_] := If[Last@list === 0, f@Most[list], list]
f2[list_] := NestWhile[Most, list, Last[#] === 0 &]
I also implemented some of the methods that were already posted here:
f3[list_] := Flatten@If[MatchQ[Last@#, {0 ..}], Most@#, #] &@Split@list
f4[list_] := Replace[list, {x___, 0 ..} :> {x}]
Personally, I was most interested in how these different realizations would perform for various numbers of padding zeros. So I wrote a small testing function:
testFunc[f_] := Block[
{list},
list = {10 - Length[f[#]], First@AbsoluteTiming[f[#]]} & /@
RandomInteger[{0, 1}, {100000, 10}];
list = Last@Reap[Sow[#[[2]], #[[1]]] & /@ list, Range[0, 10],
Mean[#2] &]
]
This will apply the function f
to 100000 random arrays of 1s and 0s of length 10. The output is the mean absolute timing of the evaluation, where I distinguish between the number of removed 0s. Here is a comparision of the four implented functions:
ListPlot[Flatten /@ (testFunc /@ {f1, f2, f3, f4}),
Joined -> True, InterpolationOrder -> 0, Axes -> False, Frame -> True,
DataRange -> {0, 10}, PlotLegends -> {"f1", "f2", "f3", "f4"}]
Interestingly, there seem to be two general trends:
- f1 and f2 both scale more or less linearly, which is to be expected of a recursive function. f2 seems to be slightly more effective. My best guess is that this can be attributed to the internal optimization for
Nest
.
- f3 and f4 only depend weakly on the number of trailing 0s to be removed and even get more effective when the padding gets larger.
So, while the function definition does seem a little bit complex, the original code of Everett You does seem to be the most efficient one in most cases.
Internal`DeleteTrailingZeros
- a neat internal function I learned about from kguler - upvote that post. $\endgroup$