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>
- Re: Re: Pick function
- References:
- Pick function
- From: Zdenek Buk <zdenek@buk.cz>
- Pick function