The key is the 4th line: note that the pattern is applied to the full list, at level 0. The full list selection does match (because it is not structurally equivalent to 0) thus the full first argument is picked out.

The reason why we don't see this behavior with Equal (i.e. ==) is that {0, 1.2, 3, 0., 5} != 0 stays unevaluated.

(I did not find a way to restrict at which levels Pick operates, but it is possible to tweak the pattern instead, e.g. elem_?NumericQ/;elem=!=0, possibly with a performance hit.)

Does it mean that the patt in Pick[list, sel, patt] is not mapped over list and sel in this case? That is contradicting the help, I think.
–
István ZacharMay 1 '12 at 11:54

1

@István It seems that Pick compares list and sel at every level, successively, including level 0. Once a level matches, it picks everything from there. If it doesn't, it looks at deeper levels. Another example would be Pick[{1, 2, {x, y, z}}, {1, 2, {a, b, c}}, a_ /; Length[a] == 3]. The full list is picked. If we change 1, 2 to 1, 2, 3 in both lists to make them length 4, only the last element will be picked.
–
SzabolcsMay 1 '12 at 11:57

1

@gwr I agree that it's really confusing. If it weren't for Trace, I would have believed it was a bug ...
–
SzabolcsMay 1 '12 at 12:00

6

Then I really wonder why Pick does not have a 4th argument for level specification...
–
István ZacharMay 1 '12 at 12:07

1

@Szabolcs +1. As to Cases: "once an element has matched, it will still look at its sub-elements" - this actually happens the other way around: Cases uses a depth-first traversal (which causes some other effects as well), so it sees the parts before it sees the expression as a whole.
–
Leonid ShifrinMay 1 '12 at 12:30

Thank you, Markus, but I wanted to explicitedly make a difference between a Null-entry as in a sparse array and a numerical Value of 0. That is why I used =!= instead of !=.
–
gwrMay 1 '12 at 12:09

@gwr: If your goal is to find the elements which are explicitly in the sparse array, you can use DeleteCases[#[[1,1]]&/@ArrayRules[yoursparsearray],Verbatim[_]] or, if the array might be multi-dimensional, DeleteCases[#[[1]]&/@ArrayRules[yoursparsearray],{Verbatim[_]...}]
–
celtschkMay 2 '12 at 13:52

Mathematica is a registered trademark of Wolfram Research, Inc. While the mark is used herein with the limited permission of Wolfram Research, Stack Exchange and this site disclaim all affiliation therewith.