MathGroup Archive 2012

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: How to use Pick[]; Is this a bug?

On 8/22/12 at 2:24 AM, awnl at (awnl) wrote:

>>>In[1]:=  Pick[{1, 2, 3, 4, 5}, {9, 0, 7, 0, 6}, Except[0]]
>>>Out[1]:= {1, 2, 3, 4, 5}

>>>Shouldn't this return {1, 3, 5}, since these are the corresponding
>>>elements that match Except[0]?

>>the whole list {9, 0, 7, 0, 6} is unequal to the Integer 0.

>that's an explanation of what goes wrong, but it still looks very
>much like a bug to me: Nothing in the documentation gives a hint
>that the second argument as a whole would ever be tried to match the
>third argument -- and it wouldn't seem to make any sense to do so
>for the given functionality...

Sigh... Yes, documentation can be improved. But it truly isn't
accurate to say "nothing in the documentation gives a hint...".
The key point is the syntax specified for Pick, i.e.,

Pick[list, sel, patt]

The important part is patt short for pattern, telling you Pick
is doing pattern matching. Other parts of the documentation
discussion pattern matching and how Mathematica goes about it
point out Mathematica tries to match the entire expression with
the specified pattern.

That is:

In[1]:= MatchQ[{9, 0, 7, 0, 6}, Except[0]]

Out[1]= True

which is why the entire list is returned.

>> What you want is:

>> Pick[{1, 2, 3, 4, 5}, {9, 0, 7, 0, 6}, Except[0, _Integer]]

>that's of course a very useful workaround

This truly isn't a workaround. What is being done here is to
specify a more specific pattern that ensures it no longer
matches the entire expression. So, Mathematica tries to match
parts of the expression.

This same issue comes up anytime you use pattern matching. For
example consider:

In[2]:= data = RandomInteger[10, {3, 2}]

Out[2]= {{9, 2}, {0, 9}, {1, 3}}

In[3]:= data /. {a_, b_} -> {a - b, a + b}

Out[3]= {{7, 11}, {-9, 9}, {-2, 4}}

My pattern looks for a two element list an replaces each two
element list with the difference and sum of the elements it
contains. And since the entire expression is a 3 element list
with each element being a two element list, the entire list is
not matched and I get the expected result.

But look what happens if I drop the first element of data using Rest

In[4]:= Rest[data] /. {a_, b_} -> {a - b, a + b}

Out[4]= {{-1, 6}, {1, 12}}

Now the pattern does match the entire list and I get a much
different result. And like the example with Pick, I can specify
the pattern as {a_Integer,b_} which will prevent matching the
entire expression.

These details of pattern matching are not repeated in the
documentation for every function that uses pattern matching. But
this information is in the documentation. And pattern matching
in this case is working as documented.

  • Prev by Date: Re: Non-sequential composition of pure functions
  • Next by Date: Re: Problems with dynamic tables
  • Previous by thread: Re: How to use Pick[]; Is this a bug?
  • Next by thread: Re: How to use Pick[]; Is this a bug?