How to use `Except[]` inside of `Pick[]`
This works:
Block[{Pick}, Thread@Pick[{1, 2}, {0, 1}, Except[0]]]
This is due to the fact that Pick[1,0,Except[0]]
also works and gives Sequence[]
. It appears, the pattern is working first on the whole expression. As {0, 1}
matches Except[0]
, it gives true and the corresponding element is the entire list {1, 2}
.
Another quick workaround is this:
Pick[{1, 2}, {0, 1}, Except[0, Except[_List]]]
Here's a test to illustrate my PS:
Pick[{1, 2*x}, {0, x + 2}, Except[0, patt_ /; AtomQ[patt]]]
The internal forms of the list and selector are:
{1, Times[2,x]}
{0, Plus[2,x]}
As you can see, the nesting of the structures is identical, but the heads differ. Nonetheless, Pick
disregards the fact that Times
and Plus
are not the same and returns {2 x}
. IMO, maybe Pick
is in over its head with generality.
PS
As Szabolcs comments, this was already discussed in the dupe + linked Q. I might add to the discussion, that since Pick
is a very general function, that's designed to work on (1) arbitrarily shaped nested structures, and (2) the heads of which are not necessarily List
, there is some logic, that the easy way out is to go through a top-level first, complete-expression first search routine. It, of course, has some caveats, such as this one.
Looks like Except
doesn't work in Pick
pattern matching. Here's a workaround.
Pick[{1, 2, 3, 4}, {0, 1, 0, 2}, _?(# != 0 &)]
{2, 4}
Or similar to the form in Pick: Possible Issues (last example)
list = {1, 2, 3, 4};
selector = {0, 1, 0, 2};
newSelector = Map[MatchQ[#, Except[0]] &, {0, 1, 0, 2}];
Pick[list, newSelector]
{2, 4}