MathGroup Archive 2005

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

Search the Archive

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


















  • Prev by Date: Re: UpValues for expressions headed by a string
  • Next by Date: Re: Types in Mathematica thread
  • Previous by thread: Pick function
  • Next by thread: Re: Re: Pick function