7
$\begingroup$

Imagine I have two lists:

List1 = {0, 1, 0.6, 0.5, 1.2, 0.4};
List2 = {"a", "b", "c", "d", "e", "f"};

How can I use Pick to return a third list consisting of items in List2 that have a array position corresponding to an array position with a value $\leq N$ in the first list? Here, for example, for $N = 0.5$ we should have:

List3 = {"a", "d", "f"}
$\endgroup$
1
  • $\begingroup$ Without Pick: Last /@ Select[Transpose@{List1, List2}, #[[1]] <= 0.5 &] $\endgroup$
    – rm -rf
    Jul 15, 2013 at 1:06

2 Answers 2

9
$\begingroup$

Several ways to create the stencil. Perhaps most intuitive is just to run a test:

stencil = # <= 0.5 & /@ List1

Pick[List2, stencil]
(*  {"a", "d", "f"}  *)

Edit

To answer the comment below, Pick "picks out those elements of list for which the corresponding element of sel is True" so the second list as argument to Pick has to be a list of True/False unless a specific pattern is specified.

So the "default" approach above creates a new list of True/False from List1. An alternative is to specify a pattern:

Pick[List2, List1, x_ /; x <= 0.5]
(* {"a", "d", "f"} *)

or

Pick[List2, List1, _?(# <= 0.5 &)]
(* {"a", "d", "f"} *)
$\endgroup$
4
  • $\begingroup$ I appreciate your answer. This may sound like an odd comment, however, how was I supposed to know how to do that? I spent some time reading the manual before asking this question, and it still wasn't clear how to get the syntax right to solve the problem myself. $\endgroup$ Jul 15, 2013 at 1:15
  • 1
    $\begingroup$ In version 8, Pick has improved performance for a packed array stencil (or, as I would call it, mask). One can generate this using a compiled function, in case the test is more complex than a simple threshold. If a threshold's all that's required, chyanog's approach accomplishes the same thing more simply. @SparsePine with over 4000 functions, nobody could be expected to learn and remember them all. This kind of thing comes from experience and, since Pick has been around for a while, perhaps there is also an advantage to having used Mathematica since it was a much smaller system. $\endgroup$ Jul 15, 2013 at 4:52
  • $\begingroup$ @OleksandrR. I was trying to keep it simple :) $\endgroup$ Jul 15, 2013 at 5:17
  • $\begingroup$ @SparsePine Pick is full of surprises and its actual behaviour not very well documented. See this conversation in chat where some long-time users are puzzled by its behaviour. $\endgroup$ Jul 15, 2013 at 8:20
12
$\begingroup$

You can also use UnitStep, it has the Listable attribute, listable operations will be faster than other alternatives.

List1 = {0, 1, 0.6, 0.5, 1.2, 0.4};
List2 = {"a", "b", "c", "d", "e", "f"};
Pick[List2, UnitStep[0.5 - List1], 1]
(*{"a", "d", "f"}*)
$\endgroup$

Your Answer

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

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