Pick[{1, 2}, {0, 1}, Except[0]]
returns {1, 2}
, the first element of which I did expect to be excluded. What is the thing I don't understand?!
Pick[{1, 2}, {0, 1}, Except[0]]
returns {1, 2}
, the first element of which I did expect to be excluded. What is the thing I don't understand?!
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.
Except
does work. It's just thrown by the sequence functionality.
$\endgroup$
Commented
Apr 26, 2016 at 14:35
Pick[{1, 2, 3, 4}, {0, 1, 0, 2}, Except[0 | _List]]
also works. (+1)
$\endgroup$
Pick[{1, 2, 3, 4}, {0, 1, 0, 2}, Except[0, _Integer]]
$\endgroup$
Except[0 | _List]
is cleaner than Except[0, Except[_List]]
. If you feel sufficiently strongly about this, you're welcome to edit it into the answer.
$\endgroup$
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}