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

*To*: mathgroup at smc.vnet.net*Subject*: [mg127798] Re: How to use Pick[]; Is this a bug?*From*: Bill Rowe <readnews at sbcglobal.net>*Date*: Thu, 23 Aug 2012 02:53:43 -0400 (EDT)*Delivered-to*: l-mathgroup@mail-archive0.wolfram.com*Delivered-to*: l-mathgroup@wolfram.com*Delivered-to*: mathgroup-newout@smc.vnet.net*Delivered-to*: mathgroup-newsend@smc.vnet.net

On 8/22/12 at 2:24 AM, awnl at gmx-topmail.de (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.