0
$\begingroup$

I tried to test if a list has non-numeric elements using FreeQ as follows:

FreeQ[{"sa", "sa", {"sa", "sa"}, x}, Except[_?NumericQ], {-1}]

which gives False and apparently contradicts what I expect as the list doesn't contain any numeric element.

How can this behavior of FreeQ be explained?


Edit

I realised the mistake I made in the previous example.

However, for the case below

{FreeQ[{1, 2, 2, 1}, Except[_?NumericQ], {-1}], FreeQ[{1, 2, 2, 1}, _?NumericQ, {-1}]}

I would expect {True,False} but it gives {False,False}.

Is there something I'm still missing?

$\endgroup$
  • 1
    $\begingroup$ Heads->False... $\endgroup$ – ciao Aug 10 '16 at 7:09
  • $\begingroup$ Thanks @ciao. Does that mean Mathematica actually tests Integer[1] rather than 1? $\endgroup$ – sunt05 Aug 10 '16 at 7:11
  • 1
    $\begingroup$ No, try putting a Print or Sow in the test - you'll see without Heads->False, the list head itself is also passed to test... $\endgroup$ – ciao Aug 10 '16 at 7:13
  • $\begingroup$ Now I get it. Thanks so much, @ciao! $\endgroup$ – sunt05 Aug 10 '16 at 7:14
3
$\begingroup$

With your code, you are asking: "Keep checking until you find an instance of this pattern. If that instance exists, return false. Return true otherwise." Your pattern is "not a number". Hence, FreeQ checks the first item, finds it is not a number, returns false. Use the following code to track which elements are being tested. I removed the offending Except call to avoid the double negation.

FreeQ[{"sa", "sa", {"sa", "sa"}, 
  x}, _?((Print[#]; NumericQ[#]) &), {-1}, Heads -> False]
$\endgroup$
  • $\begingroup$ Heads -> False saved me. I didn't notice this option. Also the Print helps locating the issue. $\endgroup$ – sunt05 Aug 10 '16 at 7:33
4
$\begingroup$

You have simply inverted the pattern you should have used, which is _?NumericQ. You are asking, "Is my list free of things that are not numerics?", when you really meant to ask is, "Is my list free of that are numerics?"

Your error is analogous to the common beginner error in procedural languages of writing

i = 1; While[i > 5, ++i]; i

when the coder really meant to write

i = 1; While[i < 5, ++i]; i

and wondering why the result is 1 and not 5,

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.