10
$\begingroup$
x = {4, 1, 2, 5, 6, 7}
y = {1, 2, 4, 5, 6, 9}

There are two lists x and y. How to find out these positions of the elements in list x are smaller than those in corresponding list y and get the following results:

{2, 3, 6}
$\endgroup$
1
  • 3
    $\begingroup$ Just for fun: SparseArray[Ramp[y-x]]["NonzeroPositions"] $\endgroup$
    – user1066
    Commented Apr 10, 2023 at 13:30

7 Answers 7

10
$\begingroup$
Flatten@Position[Negative[x - y], True]

Also possible:

Flatten@Position[x - y, _?(# < 0 &)]

or, as suggested by J.M.,

Flatten[Position[x - y, _?Negative]]
$\endgroup$
4
  • 1
    $\begingroup$ +1, nice use of Negative! $\endgroup$
    – corey979
    Commented Feb 3, 2020 at 13:13
  • 1
    $\begingroup$ @corey979 Thanks, I wonder why it is not called NegativeQ rather than Negative btw... ! $\endgroup$
    – anderstood
    Commented Feb 3, 2020 at 13:15
  • 3
    $\begingroup$ @anders, because Negative[] and similar functions don't have to immediately evaluate to True/False (while *Q[] functions do so), which makes them usable in assumptions like Assuming[Negative[x], Simplify[UnitStep[x]]]. (On that note, you can do your last one as Flatten[Position[x - y, _?Negative]]) $\endgroup$ Commented Feb 3, 2020 at 13:26
  • $\begingroup$ @J.M. Thank you for the explanation! $\endgroup$
    – anderstood
    Commented Feb 3, 2020 at 13:28
10
$\begingroup$
Flatten @ Position[Less @@@ Transpose[{x, y}], True]
$\endgroup$
1
  • 3
    $\begingroup$ Equivalently: Flatten[Position[Thread[x < y], True]] $\endgroup$ Commented Feb 3, 2020 at 13:27
9
$\begingroup$
PositionIndex[Sign[x - y]] @ -1

{2, 3, 6}

Also

PositionIndex[UnitStep[x - y]] @ 0 (* thanks: J.M. *)

{2, 3, 6}

PositionIndex[Negative[x - y]] @ True (* thanks: anderstood *)

{2, 3, 6}

PositionIndex[Thread[x < y]]@True

{2, 3, 6}

If you prefer to have {} (rather than Missing["KeyAbsent", _]) as output when no positions satisfy the condition, you can use

Lookup[PositionIndex[Sign[x - y]], -1, {}]
Lookup[PositionIndex[UnitStep[x - y]], 0, {}]
Lookup[PositionIndex[Negative[x - y]], True, {}]
Lookup[PositionIndex[Thread[x < y]], True, {}]

for the four approaces above.

$\endgroup$
3
  • 4
    $\begingroup$ Another equivalent for the first: Lookup[PositionIndex[UnitStep[x - y]], 0]. $\endgroup$ Commented Feb 3, 2020 at 13:37
  • 2
    $\begingroup$ Also: PositionIndex[Negative[x - y]][True] $\endgroup$
    – anderstood
    Commented Feb 3, 2020 at 14:04
  • 1
    $\begingroup$ Thank you both J.M. and @anderstood. I added your suggestions. $\endgroup$
    – kglr
    Commented Feb 3, 2020 at 14:09
4
$\begingroup$
x = {4, 1, 2, 5, 6, 7};
y = {1, 2, 4, 5, 6, 9};

Using SequencePosition

First /@ SequencePosition[Transpose[{x, y}], {a_} /; Less @@ a]

{2, 3, 6}

Using MapThread

First /@ Position[True] @ MapThread[Less, {x, y}]

{2, 3, 6}

$\endgroup$
4
$\begingroup$

Using MapIndexed:

x = {4, 1, 2, 5, 6, 7};
y = {1, 2, 4, 5, 6, 9};

MapIndexed[If[Less @@ #1, First@#2, Nothing] &, Transpose@{x, y}]

Using Inner:

Inner[Less, x, y, List] // Position[True] // Map[First]

Result:

{2, 3, 6}

$\endgroup$
4
$\begingroup$

Using Position and Condition:

Sequence @@@ Position[Thread[{x, y}], {x_, y_} /; x < y]

(*{2, 3, 6}*)

Or using SubsetPosition and Select:

First@SubsetPosition[#, Select[#, Less @@ # &]] &@Thread[{x, y}]

(*{2, 3, 6}*)

Another way using Pick and Thread`:

Keys@Pick[Thread[Range@Length@# -> #] &@#, Less @@@ #] &@Thread[{x, y}]

(*{2, 3, 6}*)
$\endgroup$
1
  • 1
    $\begingroup$ This use of SubsetPosition is new to me. Very useful. Already upvoted $\endgroup$
    – eldo
    Commented Feb 10 at 8:00
3
$\begingroup$
{4, 1, 2, 5, 6, 7} - {1, 2, 4, 5, 6, 9} // MapIndexed[
    If[# < 0,
        First @ #2
        ,
        Nothing
    ]&
]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.