We can use SparseArray
. It computes all the positions, but it's a bit faster than Position
, esp. on packed arrays, since Position
unpacks a packed array.
First @ SparseArray[packedarray]["NonzeroPositions"]
or
First @ SparseArray[Developer`ToPackedArray @ unpackedlist]["NonzeroPositions"]
Timings on ten random lists:
SeedRandom[1];
n = 10;
list = RandomChoice[{0.9, 0.1} -> {0, 1}, {n, 100000}];
packedlist = Developer`ToPackedArray @ list;
Table[
First @ SparseArray[Developer`ToPackedArray @ list[[i]]]["NonzeroPositions"],
{i, n}] // AbsoluteTiming
Table[
Position[list[[i]], _?(# != 0 &), 1, 1],
{i, n}] // AbsoluteTiming
Table[
First @ SparseArray[packedlist[[i]]]["NonzeroPositions"],
{i, n}] // AbsoluteTiming
Table[
Position[packedlist[[i]], _?(# != 0 &), 1, 1],
{i, n}] // AbsoluteTiming
{0.007372, {{15}, {28}, {4}, {20}, {13}, {2}, {8}, {7}, {42}, {9}}}
{0.009183, {{{15}}, {{28}}, {{4}}, {{20}}, {{13}}, {{2}}, {{8}}, {{7}}, {{42}}, {{9}}}}
{0.005098, {{15}, {28}, {4}, {20}, {13}, {2}, {8}, {7}, {42}, {9}}}
{0.024295, {{{15}}, {{28}}, {{4}}, {{20}}, {{13}}, {{2}}, {{8}}, {{7}}, {{42}}, {{9}}}}
Compiled
It's rather straightforward in an imperative paradigm:
firstnzp = Compile[{{list, _Integer, 1}},
Do[If[list[[i]] != 0, Return[i]], {i, Length@list}],
RuntimeOptions -> "Speed"
]
And fast:
Table[firstnzp @ list[[i]], {i, n}] // AbsoluteTiming
{0.004164, {15, 28, 4, 20, 13, 2, 8, 7, 42, 9}}
FirstPosition[A, _?(# != 0 &)]
$\endgroup$