Re: Pick function

*To*: mathgroup at smc.vnet.net*Subject*: [mg62928] Re: [mg62906] Pick function*From*: Andrzej Kozlowski <akoz at mimuw.edu.pl>*Date*: Thu, 8 Dec 2005 03:36:03 -0500 (EST)*References*: <200512080504.AAA11713@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

On 8 Dec 2005, at 14:04, Zdenek Buk wrote: > Hi All, > > I have found a strange behavior of the "Pick" function. > > Testing data: > ------------ > In[1]:= > l = {1, a -> b, x, c -> 1, d -> e + f, g + h} > > Out[1]:= > {1, a -> b, x, c -> 1, d -> e + f, g + h} > > In[2]:= > l2=Table[i,{i,Length[l]}] > > Out[2]= > {1,2,3,4,5,6} > > > Now try to select the "Rules": > ----------------------------- > In[3]:= > Cases[l,x:(_->_)] > > Out[3]= > {a->b,c->1,d->e+f} > > OK, this is what I expected. > > but... > > Try to use the Pick function: > ---------------------------- > > In[4]:= > sel1=Pick[l,l,_->_] > > Out[4]= > {a->b,c->1,d->e+f,0} > > In[5]:= > sel2=Pick[l2,l,_->_] > > Out[5]= > {2,4,5} > > > As you can see, the the first command returned 4 items, but the second > command returned only 3 items (as expected). > I really don't understand why there is the last "0" value in "sel1" > list. > > I expected, that "Pick[l,l,_->_]" command should return: > "{a->b,c->1,d->e+f}". > > > Is here somebody who can explain this strange behavior for me, please? > > I think I can explain it but the explanation will be a bit longish... First observe this: Pick[{g[x]}, {g[x]}, _anything] {g[]} This may not seem obviously related to your question, so let's do it with a two argument function: Pick[{g[x, y]}, {g[x, y]}, _anything] {g[]} Now, to see the point more clearly let's put g=Plus; Pick[{g[x, y]}, {g[x, y]}, _anything] {0} The reason you got 0 was that Plus with no arguments returns 0. That is Plus[] 0 If you use Times instead of Plus you will get 1 (so if you have e*f instead of e+f in your l you will end up with a 1). Next, observe, that we do not really need to put g[x] into a list, because Pick works with expressions other than lists. Look carefully what happens: Clear[g] Pick[g[x, y], g[x, y], _anything] g[] What happened here? Nothing in the expression g[x,y] matches and object with head "anything" so nothing was found. But what was returned was not the empty list {} but the expression g[], since we used head g instead of lists in Picking. Next observe that Pick also works with nested lists and nested expressions with different Heads. So let's look back again at the first example: Pick[{g[x]}, {g[x]}, _anything] {g[]} So now we can understand what happened here. No matches were found so there was nothing to return. But to preserve the structure of the nested expression the heads were kept as they appeared in Pick, thus we got: {g[]} In particular Pick[{{x}, {{[x}}, _anything] Out[13]= {{}} Which looks more reasonable. O.K. So finally your original example: Clear[g] l={1, a -> b, x, c -> 1, e + f, g + h} First, look at it in FullForm: FullForm[l] List[1,Rule[a,b],x,Rule[c,1],Plus[e,f],Plus[g,h]] Let's first do what you did but try to Pick objects with Head "anything" (there aren't any): Pick[l, l, _anything] (Error messages about Rule being called with 0 arguments). {Rule[], Rule[], 0, 0} Clearly, Pick considered all the expressions with heads Rule and Plus as being "nested" and it tried to find match the pattern "inside them" but found nothing to match. So it returned nothing, but with the Heads of expressions wrapped round it. So Rule got returned with no arguments and hence the error message. Plus was returned also with no arguments, but Plus[] is defined and returns 0. Finally, let's run the above but with the pattern _Rule In[4]:= Pick[l, l, _Rule] Out[4]= {a -> b, c -> 1, 0, 0} Well we see that where Pick found a match on the first level of the expression it did not try to look "inside" for any more matches and returned the two level 1 subexpressions with Head Rule. But in the cases when it could not find anything on the first level, it decided to look at the next level and having found nothing there returned the Head of the expression wrapped around nothing. I am not completely sure whether this was entirely intended by the designer's of Pick and whether it would not be better if Pick had an option specifying the level at which the attempted matching should take place, but in any case, it shows that you have to use it carefully. Andrzej Kozlowski

**Follow-Ups**:**Re: Re: Pick function***From:*"Oyvind Tafjord" <tafjord@wolfram.com>

**References**:**Pick function***From:*Zdenek Buk <zdenek@buk.cz>